﻿///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2023, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область СлужебныйПрограммныйИнтерфейс

// Параметры:
//  Форма - ФормаКлиентскогоПриложения
//  Элемент - ПолеФормы
//          - РасширениеПоляФормыДляПоляТабличногоДокумента
//  Область - ОбластьЯчеекТабличногоДокумента
//
Процедура ПоказатьКонтекстнуюНастройкуОтчета(Форма, Элемент, Область, СтандартнаяОбработка) Экспорт 
	
	Если ТипЗнч(Область) <> Тип("ОбластьЯчеекТабличногоДокумента")
		Или Область.ТипОбласти <> ТипОбластиЯчеекТабличногоДокумента.Прямоугольник
		Или Область.Расшифровка <> Неопределено
		И ТипЗнч(Область.Расшифровка) <> Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
		
		Возврат;
	КонецЕсли;
	
	НастройкиОтчета = Форма.НастройкиОтчета; // см. ВариантыОтчетов.НастройкиФормыОтчета
	СвойстваРезультата = НастройкиОтчета.СвойстваРезультата; // см. ВариантыОтчетовСлужебный.СвойстваРезультатаОтчета
	
	Заголовки = СвойстваРезультата.Заголовки;
	
	Область = Элемент.ТекущаяОбласть; // ОбластьЯчеекТабличногоДокумента
	СвойстваЗаголовка = Заголовки[Область.Имя]; // 
	
	Если ТипЗнч(СвойстваЗаголовка) <> Тип("Структура")
		Или ТипЗнч(СвойстваЗаголовка.Поле) <> Тип("ПолеКомпоновкиДанных")
		Или СвойстваЗаголовка.ТипЗначения.Типы().Количество() = 0 
		Или СвойстваЗаголовка.ПорядокРаздела <> 1 Тогда 
		
		Возврат;
	КонецЕсли;
	
	КомпоновщикНастроек = КомпоновщикНастроекОтчета(Форма);
	
	КэшЗначенийОтборов = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(
		КомпоновщикНастроек.ПользовательскиеНастройки.ДополнительныеСвойства, "КэшЗначенийОтборов", Новый Соответствие);
	
	ПараметрыФормы = Новый Структура;
	ПараметрыФормы.Вставить("НастройкиОтчета", НастройкиОтчета);
	ПараметрыФормы.Вставить("КомпоновщикНастроек", КомпоновщикНастроек);
	ПараметрыФормы.Вставить("ДанныеРасшифровки", Форма.ОтчетДанныеРасшифровки);
	ПараметрыФормы.Вставить("Документ", Форма.ОтчетТабличныйДокумент);
	ПараметрыФормы.Вставить("Заголовки", Заголовки);
	ПараметрыФормы.Вставить("СвойстваЗаголовка", СвойстваЗаголовка);
	ПараметрыФормы.Вставить("КэшЗначенийОтборов", КэшЗначенийОтборов);
	
	ОткрытьФорму(
		"ХранилищеНастроек.ХранилищеВариантовОтчетов.Форма.НастройкаПоля",
		ПараметрыФормы,
		Форма,
		Форма.УникальныйИдентификатор);
	
	СтандартнаяОбработка = Ложь
	
КонецПроцедуры

// Параметры:
//  Форма - ФормаКлиентскогоПриложения
//  Элемент - ПолеФормы
//          - РасширениеПоляФормыДляПоляТабличногоДокумента
//  Расшифровка - ИдентификаторКомпоновкиДанных
//  СтандартнаяОбработка - Булево
//
Процедура ОбработкаРасшифровки(Форма, Элемент, Расшифровка, СтандартнаяОбработка) Экспорт 
	
	НастройкиОтчета = Форма.НастройкиОтчета; // см. ВариантыОтчетов.НастройкиФормыОтчета
	СвойстваРезультата = НастройкиОтчета.СвойстваРезультата; // см. ВариантыОтчетовСлужебный.СвойстваРезультатаОтчета
	ТекущаяОбласть = Элемент.ТекущаяОбласть; // ОбластьЯчеекТабличногоДокумента
	
	Заголовки = СвойстваРезультата.Заголовки[ТекущаяОбласть.Имя];
	
	Если ТипЗнч(Заголовки) = Тип("Структура") Тогда 
		
		СтандартнаяОбработка = Ложь;
		Форма.Элементы.КонтекстноеМенюОбластиЗаголовка.Видимость = Истина;
		
	КонецЕсли;
	
КонецПроцедуры

Процедура ОбработкаДополнительнойРасшифровки(Форма, Данные, Элемент, Расшифровка, СтандартнаяОбработка) Экспорт 
	
	Если Данные = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	СвойстваОбласти = СвойстваОбластиРасшифровки(Форма, Элемент.ТекущаяОбласть, Данные.Поле);
	
	Если ТипЗнч(СвойстваОбласти) <> Тип("Структура")
		Или ТипЗнч(СвойстваОбласти.СвойстваЗаголовка) <> Тип("Структура") Тогда 
		
		Возврат;
	КонецЕсли;
	
	ОсновноеМеню = Новый Массив;
	
	Если СвойстваОбласти.ЭтоЗаголовок Тогда 
		
		СвойстваЗаголовка = СвойстваОбласти.СвойстваЗаголовка;
		
		Если ТипЗнч(СвойстваЗаголовка.Поле) <> Тип("ПолеКомпоновкиДанных")
			Или СвойстваЗаголовка.ТипЗначения.Типы().Количество() = 0 Тогда 
			
			Возврат;
		КонецЕсли;
		
		ДополнительноеМеню = КонтекстноеМенюОбластиЗаголовка();
	Иначе
		ОсновноеМеню.Добавить(ДействиеОбработкиРасшифровкиКомпоновкиДанных.Расшифровать);
		ДополнительноеМеню = КонтекстноеМенюОбластиДанных(СвойстваОбласти.СвойстваЗаголовка, Данные.ДоступныеВидыСравнения);
	КонецЕсли;
	
	ОбработкаРасшифровки = Новый ОбработкаРасшифровкиКомпоновкиДанных(
		Форма.ОтчетДанныеРасшифровки, Новый ИсточникДоступныхНастроекКомпоновкиДанных(Форма.НастройкиОтчета.АдресСхемы));
	
	ДополнительныеПараметры = Новый Структура;
	ДополнительныеПараметры.Вставить("Форма", Форма);
	ДополнительныеПараметры.Вставить("Данные", Данные);
	ДополнительныеПараметры.Вставить("Расшифровка", Расшифровка);
	ДополнительныеПараметры.Вставить("ОбработкаРасшифровки", ОбработкаРасшифровки);
	ДополнительныеПараметры.Вставить("СвойстваОбласти", СвойстваОбласти);
	ДополнительныеПараметры.Вставить("Меню", ДополнительноеМеню);
	
	ПолеОтчета = Форма.Элементы.ОтчетТабличныйДокумент; // ПолеТабличногоДокумента
	
	Обработчик = Новый ОписаниеОповещения("ВыполнитьРасшифровку", ЭтотОбъект, ДополнительныеПараметры);
	ОбработкаРасшифровки.ПоказатьВыборДействия(Обработчик, Расшифровка, ОсновноеМеню, ДополнительноеМеню,, ПолеОтчета);
	
	СтандартнаяОбработка = Ложь;
	
КонецПроцедуры

// Параметры:
//  Форма - ФормаКлиентскогоПриложения
//  Элемент - ПолеФормы
//          - РасширениеПоляФормыДляПоляТабличногоДокумента
//
Процедура ПриАктивизацииРезультатаОтчета(Форма, Элемент) Экспорт 
	
	Область = Элемент.ТекущаяОбласть; // ОбластьЯчеекТабличногоДокумента
	
	Если ТипЗнч(Область) <> Тип("ОбластьЯчеекТабличногоДокумента") Тогда 
		Возврат;
	КонецЕсли;
	
	НастройкиОтчета = Форма.НастройкиОтчета; // см. ВариантыОтчетов.НастройкиФормыОтчета
	СвойстваРезультата = НастройкиОтчета.СвойстваРезультата; // см. ВариантыОтчетовСлужебный.СвойстваРезультатаОтчета 
	Элементы = Форма.Элементы;
	ПолеОтчета = Элементы.ОтчетТабличныйДокумент; // ПолеФормы, РасширениеПоляФормыДляПоляТабличногоДокумента
	
	СвойстваЗаголовка = СвойстваРезультата.Заголовки[Область.Имя];
	ЭтоРасшифровка = Область.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Прямоугольник
		И ТипЗнч(Область.Расшифровка) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных");
	
	Элементы.КонтекстноеМенюОбластиЗаголовка.Видимость = (ТипЗнч(СвойстваЗаголовка) = Тип("Структура"))
		И ТипЗнч(СвойстваЗаголовка.Поле) = Тип("ПолеКомпоновкиДанных") И СвойстваЗаголовка.ПорядокРаздела = 1;
	
	Элементы.КонтекстноеМенюОбластиДанных.Видимость = Не Элементы.КонтекстноеМенюОбластиЗаголовка.Видимость
		И ЭтоРасшифровка;
	
	Элементы.ГруппаУровниГруппировокКонтекстноеМеню.Видимость = Не ЭтоРасшифровка;
	Элементы.КонтекстноеМенюОбластиОбщееРедактирование.Видимость = Не ЭтоРасшифровка;
	
	Элементы.КонтекстноеМенюОбластиДанныхВставитьИзБуфераОбмена.Доступность = ПолеОтчета.Редактирование;
	Элементы.КонтекстноеМенюОбластиОбщееВставитьИзБуфераОбмена.Доступность = ПолеОтчета.Редактирование;
	
	ВариантыОтчетовСлужебныйКлиентСервер.ОпределитьДоступностьДействийКонтекстногоМеню(Форма, СвойстваЗаголовка);
	
	Если Элементы.КонтекстноеМенюОбластиЗаголовка.Видимость Тогда 
		
		ЗаголовокКнопки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Сгруппировать по полю %1'"), СвойстваЗаголовка.Текст);
		
		ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(
			Элементы, "КонтекстноеМенюОбластиЗаголовкаСгруппироватьПоВыбранномуПолю", "Заголовок", ЗаголовокКнопки);
		
	КонецЕсли;
	
КонецПроцедуры

Функция ЭтоСобытиеКонтекстнойНастройки(Событие) Экспорт 
	
	События = СобытияКонтекстнойНастройки();
	
	Возврат События[Событие] = Истина;
	
КонецФункции

#Область ОбработчикиКомандКонтекстногоМенюТабличногоДокументаРезультатОтчета

#Область ВставкаПоляИлиГруппировки

Процедура СгруппироватьПоВыбранномуПолю(Форма, Команда) Экспорт 
	
	Если Не ДействиеДоступно(Форма, Команда) Тогда 
		Возврат;
	КонецЕсли;
	
	СвойстваЗаголовка = СвойстваЗаголовкаОтчета(Форма);
	Настройки = ИспользуемыеНастройки(Форма, СвойстваЗаголовка.ИдентификаторНастроек);
	Настройки2 = ИспользуемыеНастройки(Форма, СвойстваЗаголовка.ИдентификаторНастроек, Истина);
	
	ВыбранноеПоле = Настройки.ДоступныеПоляГруппировок.НайтиПоле(СвойстваЗаголовка.Поле);
	Если ВыбранноеПоле = Неопределено Тогда 
		Возврат;
	КонецЕсли;
	
	Раздел = Настройки.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторРаздела);
	Раздел2 = Настройки2.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторРаздела);
	
	Если ТипЗнч(Раздел) = Тип("ТаблицаКомпоновкиДанных") Тогда 
		Группировки = Раздел.Строки;
		Группировки2 = Раздел2.Строки;
	Иначе
		Группировки = Раздел.Родитель.Структура;
		Группировки2 = Раздел2.Родитель.Структура;
	КонецЕсли;
	
	ПеремещаемыеГруппировки = Новый Массив;
	
	Для Каждого Элемент Из Группировки Цикл 
		ПеремещаемыеГруппировки.Добавить(Элемент);
	КонецЦикла;
	
	ДетальныеЗаписи = ДетальныеЗаписи(Группировки2);
	
	Если ТипЗнч(Группировки) = Тип("КоллекцияЭлементовСтруктурыНастроекКомпоновкиДанных") Тогда 
		НоваяГруппировка = Группировки.Вставить(0, Тип("ГруппировкаКомпоновкиДанных")); // ГруппировкаКомпоновкиДанных
	Иначе
		НоваяГруппировка = Группировки.Вставить(0);
	КонецЕсли;
	
	НовоеПоле = НоваяГруппировка.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
	НовоеПоле.Поле = ВыбранноеПоле.Поле;
	НовоеПоле.Использование = Истина;
	
	НоваяГруппировка.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
	НоваяГруппировка.Порядок.Элементы.Добавить(Тип("АвтоЭлементПорядкаКомпоновкиДанных"));
	
	Если ДетальныеЗаписи <> Неопределено Тогда 
		
		ПоискЭлементов = Новый Соответствие;
		ОтчетыКлиентСервер.СкопироватьРекурсивно(
			Настройки, ДетальныеЗаписи, НоваяГруппировка.Структура, 0, ПоискЭлементов);
		
	КонецЕсли;
	
	Для Каждого Группировка Из ПеремещаемыеГруппировки Цикл 
		Группировки.Удалить(Группировка);
	КонецЦикла;
	
	ОповеститьОЗавершенииКонтекстнойНастройки(Форма, ДействиеКоманды(Команда), СвойстваЗаголовка.Текст);
	
КонецПроцедуры

Процедура ВставитьПолеСлева(Форма, Команда) Экспорт 
	
	ВыбратьПолеОтчетаИзМеню(Форма, Команда);
	
КонецПроцедуры

Процедура ВставитьПолеСправа(Форма, Команда) Экспорт 
	
	ВыбратьПолеОтчетаИзМеню(Форма, Команда);
	
КонецПроцедуры

Процедура ВставитьГруппировкуВыше(Форма, Команда) Экспорт 
	
	ВыбратьПолеОтчетаИзМеню(Форма, Команда);
	
КонецПроцедуры

Процедура ВставитьГруппировкуНиже(Форма, Команда) Экспорт 
	
	ВыбратьПолеОтчетаИзМеню(Форма, Команда);
	
КонецПроцедуры

#КонецОбласти

#Область ПеремещениеПоля

Процедура ПереместитьПолеВлево(Форма, Команда) Экспорт 
	
	ПереместитьПолеГоризонтально(Форма, Команда);
	
КонецПроцедуры

Процедура ПереместитьПолеВправо(Форма, Команда) Экспорт 
	
	ПереместитьПолеГоризонтально(Форма, Команда);
	
КонецПроцедуры

Процедура ПереместитьПолеВыше(Форма, Команда) Экспорт 
	
	ПереместитьПолеВертикально(Форма, Команда);
	
КонецПроцедуры

Процедура ПереместитьПолеНиже(Форма, Команда) Экспорт 
	
	ПереместитьПолеВертикально(Форма, Команда);
	
КонецПроцедуры

#КонецОбласти

#Область Оформление

Процедура ОчиститьОформление(Форма, СвойстваЗаголовка) Экспорт 
	
	Настройки = ИспользуемыеНастройки(Форма, СвойстваЗаголовка.ИдентификаторНастроек);
	Группировка = Настройки.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторГруппировки);
	Если ТипЗнч(Группировка) = Тип("НастройкиВложенногоОбъектаКомпоновкиДанных") Тогда
		ОчиститьОформлениеГруппировкиОтчета(Группировка.Настройки, СвойстваЗаголовка);
	ИначеЕсли СвойстваЗаголовка.КоличествоРазделов = 1 Тогда 
		ОчиститьОформлениеГруппировкиОтчета(Настройки, СвойстваЗаголовка);
	Иначе
		Раздел = Настройки.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторРаздела);
		Если ТипЗнч(Раздел) = Тип("ТаблицаКомпоновкиДанных") Тогда 
			ОчиститьОформлениеГруппировокРазделаОтчета(Раздел.Строки, СвойстваЗаголовка);
		Иначе
			ОчиститьОформлениеГруппировкиРазделаОтчета(Раздел, СвойстваЗаголовка);
		КонецЕсли;
	КонецЕсли;
	
	ОповеститьОЗавершенииКонтекстнойНастройки(Форма, "ОчиститьОформление", СвойстваЗаголовка.Текст);
	
КонецПроцедуры

Процедура ОформитьКрасным(Форма, Команда, СвойстваЗаголовка = Неопределено, Значение = Неопределено) Экспорт 
	
	Если СвойстваЗаголовка = Неопределено Тогда 
		СвойстваЗаголовка = СвойстваЗаголовкаОтчета(Форма);
	КонецЕсли;
	
	Если СвойстваЗаголовка = Неопределено Тогда 
		Возврат;
	КонецЕсли;
	
	ДействиеКоманды = ДействиеКоманды(Команда);
	
	ПараметрыРаскраски = ПараметрыРаскраскиРазделаОтчета(ДействиеКоманды);
	ПараметрыРаскраски.Условие.ЛевоеЗначение = СвойстваЗаголовка.Поле;
	
	Если ДействиеКоманды = "ОформитьОтрицательные" Тогда 
		
		Если Не ДействиеНадПолемДоступно(ДействиеКоманды, СвойстваЗаголовка) Тогда 
			Возврат;
		КонецЕсли;
		
		ПараметрыРаскраски.Условие.ВидСравнения = ВидСравненияКомпоновкиДанных.Меньше;
		ПараметрыРаскраски.Условие.ПравоеЗначение = 0;
		
		ПараметрыРаскраски.Представление = НСтр("ru = 'Оформить отрицательные красным'");
		
	Иначе
		
		ПараметрыРаскраски.Условие.ВидСравнения = ВидСравненияУсловияОформления(Значение);
		ПараметрыРаскраски.Условие.ПравоеЗначение = Значение;
		
		ПараметрыРаскраски.Представление = НСтр("ru = 'Оформить красным'");
		
	КонецЕсли;
	
	ЭлементыСтиля = СтандартныеПодсистемыКлиент.ЭлементыСтиля();
	
	Оформление = СтандартныйПараметрРаскраскиРазделаОтчета();
	Оформление.Параметр = "ЦветТекста";
	Оформление.Значение = ЭлементыСтиля.ЦветТекстаОтрицательногоЗначения;
	
	ПараметрыРаскраски.Оформление.Добавить(Оформление);
	
	Оформление = СтандартныйПараметрРаскраскиРазделаОтчета();
	Оформление.Параметр = "ЦветФона";
	Оформление.Значение = ЭлементыСтиля.ЦветФонаОтрицательногоЗначения;
	
	ПараметрыРаскраски.Оформление.Добавить(Оформление);
	
	РаскраситьРазделОтчета(Форма, ПараметрыРаскраски, СвойстваЗаголовка);
	
	ОповеститьОЗавершенииКонтекстнойНастройки(Форма, ДействиеКоманды, СвойстваЗаголовка.Текст);
	
КонецПроцедуры

Процедура ОформитьЗеленым(Форма, Команда, СвойстваЗаголовка = Неопределено, Значение = Неопределено) Экспорт 
	
	Если СвойстваЗаголовка = Неопределено Тогда 
		СвойстваЗаголовка = СвойстваЗаголовкаОтчета(Форма);
	КонецЕсли;
	
	Если СвойстваЗаголовка = Неопределено Тогда 
		Возврат;
	КонецЕсли;
	
	ДействиеКоманды = ДействиеКоманды(Команда);
	
	ПараметрыРаскраски = ПараметрыРаскраскиРазделаОтчета(ДействиеКоманды);
	ПараметрыРаскраски.Условие.ЛевоеЗначение = СвойстваЗаголовка.Поле;
	
	Если ДействиеКоманды = "ОформитьПоложительные" Тогда 
		
		Если Не ДействиеНадПолемДоступно(ДействиеКоманды, СвойстваЗаголовка) Тогда 
			Возврат;
		КонецЕсли;
		
		ПараметрыРаскраски.Условие.ВидСравнения = ВидСравненияКомпоновкиДанных.Больше;
		ПараметрыРаскраски.Условие.ПравоеЗначение = 0;
		
		ПараметрыРаскраски.Представление = НСтр("ru = 'Оформить положительные зеленым'");
		
	Иначе
		
		ПараметрыРаскраски.Условие.ВидСравнения = ВидСравненияУсловияОформления(Значение);
		ПараметрыРаскраски.Условие.ПравоеЗначение = Значение;
		
		ПараметрыРаскраски.Представление = НСтр("ru = 'Оформить зеленым'");
		
	КонецЕсли;
	
	ЭлементыСтиля = СтандартныеПодсистемыКлиент.ЭлементыСтиля();
	
	Оформление = СтандартныйПараметрРаскраскиРазделаОтчета();
	Оформление.Параметр = "ЦветТекста";
	Оформление.Значение = ЭлементыСтиля.ЦветТекстаПоложительногоЗначения;
	
	ПараметрыРаскраски.Оформление.Добавить(Оформление);
	
	Оформление = СтандартныйПараметрРаскраскиРазделаОтчета();
	Оформление.Параметр = "ЦветФона";
	Оформление.Значение = ЭлементыСтиля.ЦветФонаПоложительногоЗначения;
	
	ПараметрыРаскраски.Оформление.Добавить(Оформление);
	
	РаскраситьРазделОтчета(Форма, ПараметрыРаскраски, СвойстваЗаголовка);
	
	ОповеститьОЗавершенииКонтекстнойНастройки(Форма, ДействиеКоманды, СвойстваЗаголовка.Текст);
	
КонецПроцедуры

// Параметры:
//  Форма - ФормаКлиентскогоПриложения
//  Команда - КомандаФормы
//  СвойстваЗаголовка - см. ВариантыОтчетовСлужебный.СтандартныеСвойстваЗаголовкаОтчета
//  ВысотаСтроки - Число
//               - Неопределено
//  ПараметрыВысотыСтроки - см. ВариантыОтчетовСлужебный.СтандартныеСвойстваЗаголовкаОтчета 
//
Процедура УстановитьВысотуСтроки(Форма, Команда, СвойстваЗаголовка = Неопределено,
	ВысотаСтроки = Неопределено, ПараметрыВысотыСтроки = Неопределено) Экспорт 
	
	Если СвойстваЗаголовка = Неопределено Тогда 
		СвойстваЗаголовка = СвойстваЗаголовкаОтчета(Форма);
	КонецЕсли;
	
	Если СвойстваЗаголовка = Неопределено Тогда 
		Возврат;
	КонецЕсли;
	
	Если ВысотаСтроки = Неопределено Тогда 
		
		ПараметрыВысотыСтроки = ПараметрыРазмераПоляОтчета(Форма, СвойстваЗаголовка);
		
		ПараметрыОбработчика = Новый Структура;
		ПараметрыОбработчика.Вставить("Форма", Форма);
		ПараметрыОбработчика.Вставить("Команда", Команда);
		ПараметрыОбработчика.Вставить("СвойстваЗаголовка", СвойстваЗаголовка);
		ПараметрыОбработчика.Вставить("ПараметрыРазмераПоля", ПараметрыВысотыСтроки);
		
		Обработчик = Новый ОписаниеОповещения("ПослеВводаВысотыСтрокиОтчета", ЭтотОбъект, ПараметрыОбработчика);
		ПоказатьВводЧисла(Обработчик, ПараметрыВысотыСтроки.Размер, НСтр("ru = 'Высота строки'"), 5);
		
		Возврат;
		
	КонецЕсли;
	
	Если ПараметрыВысотыСтроки = Неопределено
		Или ПараметрыВысотыСтроки.Элемент = Неопределено Тогда 
		
		ДобавитьПараметрыРазмераПоляОтчета(Форма, СвойстваЗаголовка, ВысотаСтроки);
	Иначе
		ОбновитьПараметрыРазмера(ПараметрыВысотыСтроки, ВысотаСтроки);
	КонецЕсли;
	
	ОповеститьОЗавершенииКонтекстнойНастройки(Форма, ДействиеКоманды(Команда), СвойстваЗаголовка.Текст);
	
КонецПроцедуры

// Параметры:
//  Форма - ФормаКлиентскогоПриложения
//  Команда - КомандаФормы
//  СвойстваЗаголовка - см. ВариантыОтчетовСлужебный.СтандартныеСвойстваЗаголовкаОтчета
//  ШиринаКолонки - Число
//                - Неопределено
//  ПараметрыШириныКолонки - см. ВариантыОтчетовСлужебный.СтандартныеСвойстваЗаголовкаОтчета 
//
Процедура УстановитьШиринуКолонки(Форма, Команда, СвойстваЗаголовка = Неопределено,
	ШиринаКолонки = Неопределено, ПараметрыШириныКолонки = Неопределено) Экспорт 
	
	Если СвойстваЗаголовка = Неопределено Тогда 
		СвойстваЗаголовка = СвойстваЗаголовкаОтчета(Форма);
	КонецЕсли;
	
	Если СвойстваЗаголовка = Неопределено Тогда 
		Возврат;
	КонецЕсли;
	
	ПараметрыШириныКолонки = ПараметрыРазмераПоляОтчета(Форма, СвойстваЗаголовка, "Ширина");
	
	Если ШиринаКолонки = Неопределено Тогда 
		
		ПараметрыОбработчика = Новый Структура;
		ПараметрыОбработчика.Вставить("Форма", Форма);
		ПараметрыОбработчика.Вставить("Команда", Команда);
		ПараметрыОбработчика.Вставить("СвойстваЗаголовка", СвойстваЗаголовка);
		ПараметрыОбработчика.Вставить("ПараметрыРазмераПоля", ПараметрыШириныКолонки);
		
		Обработчик = Новый ОписаниеОповещения("ПослеВводаШириныКолонкиОтчета", ЭтотОбъект, ПараметрыОбработчика);
		ПоказатьВводЧисла(Обработчик, ПараметрыШириныКолонки.Размер, НСтр("ru = 'Ширина колонки'"), 5);
		
		Возврат;
		
	КонецЕсли;
	
	Если ПараметрыШириныКолонки = Неопределено
		Или ПараметрыШириныКолонки.Элемент = Неопределено Тогда 
		
		ДобавитьПараметрыРазмераПоляОтчета(Форма, СвойстваЗаголовка, ШиринаКолонки, "Ширина");
	Иначе
		ОбновитьПараметрыРазмера(ПараметрыШириныКолонки, ШиринаКолонки);
	КонецЕсли;
	
	ОповеститьОЗавершенииКонтекстнойНастройки(Форма, ДействиеКоманды(Команда), СвойстваЗаголовка.Текст);
	
КонецПроцедуры

Процедура ОформитьЕще(Форма, Команда, СвойстваЗаголовка = Неопределено, Значение = Неопределено) Экспорт 
	
	Если Не ДействиеДоступно(Форма,, СвойстваЗаголовка) Тогда 
		Возврат;
	КонецЕсли;
	
	ИспользуемыеНастройки = ИспользуемыеНастройки(Форма, СвойстваЗаголовка.ИдентификаторНастроек);
	Группировка = ИспользуемыеНастройки.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторГруппировки);
	
	Если ТипЗнч(Группировка) = Тип("НастройкиВложенногоОбъектаКомпоновкиДанных") Тогда
		ИдентификаторГруппировки = ИспользуемыеНастройки.ПолучитьИдентификаторПоОбъекту(Группировка);
		ИдентификаторОформления = ИдентификаторЭлементаОформленияГруппировкиОтчета(Группировка.Настройки, СвойстваЗаголовка.Поле);
	ИначеЕсли СвойстваЗаголовка.КоличествоРазделов = 1 Тогда 
		ИдентификаторГруппировки = Неопределено;
		ИдентификаторОформления = ИдентификаторЭлементаОформленияГруппировкиОтчета(ИспользуемыеНастройки, СвойстваЗаголовка.Поле);
	Иначе
		ИдентификаторГруппировки = ИспользуемыеНастройки.ПолучитьИдентификаторПоОбъекту(Группировка);
		ИдентификаторОформления = ИдентификаторЭлементаОформленияГруппировкиОтчета(Группировка, СвойстваЗаголовка.Поле);
	КонецЕсли;
	
	КомпоновщикНастроек = КомпоновщикНастроекОтчета(Форма);
	
	ПараметрыОформления = Новый Структура;
	ПараметрыОформления.Вставить("КомпоновщикНастроек", КомпоновщикНастроек);
	ПараметрыОформления.Вставить("НастройкиОтчета", Форма.НастройкиОтчета);
	ПараметрыОформления.Вставить("ИдентификаторЭлементаСтруктурыНастроек", ИдентификаторГруппировки);
	ПараметрыОформления.Вставить("ИдентификаторКД", ИдентификаторОформления);
	ПараметрыОформления.Вставить("Наименование", "");
	ПараметрыОформления.Вставить("Поле", СвойстваЗаголовка.Поле);
	ПараметрыОформления.Вставить("Условие", УсловиеОформленияГруппировкиОтчета(СвойстваЗаголовка.Поле, Значение));
	
	ПараметрыОбработчика = Новый Структура;
	ПараметрыОбработчика.Вставить("Форма", Форма);
	ПараметрыОбработчика.Вставить("ДействиеКоманды", ДействиеКоманды(Команда));
	ПараметрыОбработчика.Вставить("СвойстваЗаголовка", СвойстваЗаголовка);
	
	Обработчик = Новый ОписаниеОповещения("ПослеИзмененияЭлементаОформленияГруппировкиОтчета", ЭтотОбъект, ПараметрыОбработчика);
	
	ОткрытьФорму("ХранилищеНастроек.ХранилищеВариантовОтчетов.Форма.ЭлементУсловногоОформленияОтчета",
		ПараметрыОформления, Форма, Форма.УникальныйИдентификатор,,, Обработчик);
	
КонецПроцедуры

#КонецОбласти

#Область Фильтрация

Процедура ПоказатьРасширеннуюНастройкуФильтра(Форма, СвойстваЗаголовка) Экспорт 
	
	Если Не ДействиеДоступно(Форма,, СвойстваЗаголовка) Тогда 
		Возврат;
	КонецЕсли;
	
	НастройкиОтчета = Форма.НастройкиОтчета;
	
	Поле = Форма.Элементы.ОтчетТабличныйДокумент; // ПолеТабличногоДокумента
	ТекущаяОбласть = Поле.ТекущаяОбласть;
	
	Ячейка = Новый Структура("Текст, Расшифровка", "");
	
	Если ТекущаяОбласть.Верх <> СвойстваЗаголовка.Верх
		Или ТекущаяОбласть.Низ <> СвойстваЗаголовка.Низ
		Или ТекущаяОбласть.Лево <> СвойстваЗаголовка.Лево
		Или ТекущаяОбласть.Право <> СвойстваЗаголовка.Право Тогда 
			
		ЗаполнитьЗначенияСвойств(Ячейка, ТекущаяОбласть);
	КонецЕсли;
	
	ПараметрыФормы = Новый Структура;
	ПараметрыФормы.Вставить("КлючТекущегоВарианта", Форма.КлючТекущегоВарианта);
	ПараметрыФормы.Вставить("НастройкиОтчета", НастройкиОтчета);
	ПараметрыФормы.Вставить("КомпоновщикНастроек", КомпоновщикНастроекОтчета(Форма));
	ПараметрыФормы.Вставить("СвойстваЗаголовка", СвойстваЗаголовка);
	ПараметрыФормы.Вставить("ДанныеРасшифровки", Форма.ОтчетДанныеРасшифровки);
	ПараметрыФормы.Вставить("Ячейка", Ячейка);
	
	ОткрытьФорму(
		"ХранилищеНастроек.ХранилищеВариантовОтчетов.Форма.ФильтроватьПоПолю",
		ПараметрыФормы,
		Форма,
		Форма.УникальныйИдентификатор);
	
КонецПроцедуры

Процедура СнятьФильтр(Форма, СвойстваЗаголовка, ДанныеРасшифровки = Неопределено) Экспорт 
	
	ЭтоГруппировка = (ДанныеРасшифровки <> Неопределено
		И ДанныеРасшифровки.Тип = ВариантыОтчетовСлужебныйКлиентСервер.ТипЭлементаРасшифровкиГруппировка());
	
	Настройки = ИспользуемыеНастройки(Форма, СвойстваЗаголовка.ИдентификаторНастроек);
	
	Фильтры = ВариантыОтчетовСлужебныйКлиентСервер.ФильтрыРазделаОтчета(Настройки, СвойстваЗаголовка, ЭтоГруппировка);
	Фильтр = ВариантыОтчетовСлужебныйКлиентСервер.ФильтрРазделаОтчета(Фильтры, СвойстваЗаголовка.Поле,, Истина);
	
	Если Фильтр = Неопределено Тогда 
		
		Фильтры = ВариантыОтчетовСлужебныйКлиентСервер.ФильтрыРазделаОтчета(Настройки, СвойстваЗаголовка, Не ЭтоГруппировка);
		Фильтр = ВариантыОтчетовСлужебныйКлиентСервер.ФильтрРазделаОтчета(Фильтры, СвойстваЗаголовка.Поле,, Истина);
		
	КонецЕсли;
	
	Если Фильтр = Неопределено Тогда 
		
		ТекстПредупреждения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'По полю ""%1"" отсутствуют фильтры'"), СвойстваЗаголовка.Текст);
		
		ПоказатьПредупреждение(, ТекстПредупреждения);
		Возврат;
		
	КонецЕсли;
	
	ОповеститьОЗавершенииКонтекстнойНастройки(Форма, "СнятьФильтр", СвойстваЗаголовка.Текст);
	
КонецПроцедуры

#КонецОбласти

#Область ОстальныеДействия

Процедура СкрытьПоле(Форма, Команда) Экспорт 
	
	Если Не ДействиеДоступно(Форма, Команда) Тогда 
		Возврат;
	КонецЕсли;
	
	СвойстваЗаголовка = СвойстваЗаголовкаОтчета(Форма);
	
	Если СвойстваЗаголовка.ИдентификаторНастроек = Неопределено Тогда 
		Возврат;
	КонецЕсли;
	
	КомпоновщикНастроек2 = КомпоновщикНастроекОтчета(Форма, Истина);
	Настройки = ИспользуемыеНастройки(Форма, СвойстваЗаголовка.ИдентификаторНастроек);
	Настройки2 = ИспользуемыеНастройки(Форма, СвойстваЗаголовка.ИдентификаторНастроек, Истина);
	Раздел = Настройки.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторРаздела);
	Раздел2 = Настройки2.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторРаздела);
	
	Группировка = Настройки.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторГруппировки);
	Группировка2 = Настройки2.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторГруппировки);
	ОписаниеПоля = ОписаниеПоляОтчета(КомпоновщикНастроек2, СвойстваЗаголовка.Поле);
	
	ЭтоГруппировкаДетальныхЗаписей = ЭтоГруппировкаДетальныхЗаписей(Группировка2);
	
	Если ОписаниеПоля <> Неопределено
		И ОписаниеПоля.Ресурс Тогда 
		
		СкрытьВыбранноеПолеРаздела(Раздел, Раздел2, СвойстваЗаголовка.Поле);
	Иначе
		СкрытьВыбранноеПолеГруппировки(Группировка, Группировка2, СвойстваЗаголовка.Поле);
		
		Если Не ЭтоГруппировкаДетальныхЗаписей Тогда 
			СкрытьГруппировку(Настройки, Группировка, Настройки2, Группировка2, СвойстваЗаголовка.Поле);
		КонецЕсли;
	КонецЕсли;
	
	ОповеститьОЗавершенииКонтекстнойНастройки(Форма, ДействиеКоманды(Команда), СвойстваЗаголовка.Текст);
	
КонецПроцедуры

Процедура ПереименоватьПоле(Форма, Команда, Заголовок = "") Экспорт 
	
	Если Не ДействиеДоступно(Форма, Команда) Тогда 
		Возврат;
	КонецЕсли;
	
	СвойстваЗаголовка = СвойстваЗаголовкаОтчета(Форма);
	
	КомпоновщикНастроек2 = КомпоновщикНастроекОтчета(Форма, Истина);
	Настройки = ИспользуемыеНастройки(Форма, СвойстваЗаголовка.ИдентификаторНастроек);
	Настройки2 = ИспользуемыеНастройки(Форма, СвойстваЗаголовка.ИдентификаторНастроек, Истина);
	Группировка = Настройки.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторГруппировки);
	Группировка2 = Настройки2.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторГруппировки);
	
	ОписаниеПоля = ОписаниеПоляОтчета(КомпоновщикНастроек2, СвойстваЗаголовка.Поле);
	
	ПолеОтчета = ПолеОтчета(Группировка, Группировка2, СвойстваЗаголовка.Поле, "Выбор").Поле;
	
	Если Не ЗначениеЗаполнено(Заголовок) Тогда 
		
		ПараметрыОбработчика = Новый Структура("Форма, Команда", Форма, Команда);
		Обработчик = Новый ОписаниеОповещения("ПослеВводаЗаголовкаПоляОтчета", ЭтотОбъект, ПараметрыОбработчика);
		
		ТекущийЗаголовок = ТекущийЗаголовокПоляОтчета(ПолеОтчета, ОписаниеПоля);
		
		ЗаголовокДиалога = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Заголовок поля: %1'"),
			?(ОписаниеПоля = Неопределено, Строка(ПолеОтчета), ОписаниеПоля.Заголовок));
		
		ПоказатьВводСтроки(Обработчик, ТекущийЗаголовок, ЗаголовокДиалога);
		
		Возврат;
		
	КонецЕсли;
	
	Если ПолеОтчета <> Неопределено Тогда 
		УстановитьЗаголовокПоляОтчета(Настройки, ПолеОтчета, ОписаниеПоля, Заголовок);
	КонецЕсли;
	
	ОповеститьОЗавершенииКонтекстнойНастройки(Форма, ДействиеКоманды(Команда), СвойстваЗаголовка.Текст);
	
КонецПроцедуры

Процедура Сортировать(Форма, Команда, СвойстваЗаголовка = Неопределено) Экспорт 
	
	Если СвойстваЗаголовка = Неопределено Тогда 
		СвойстваЗаголовка = СвойстваЗаголовкаОтчета(Форма);
	КонецЕсли;
	
	Если СвойстваЗаголовка = Неопределено Тогда 
		Возврат;
	КонецЕсли;
	
	Если Не ТипСортировкиРазделаДоступен(Команда, СвойстваЗаголовка) Тогда 
		Возврат;
	КонецЕсли;
	
	Настройки = ИспользуемыеНастройки(Форма, СвойстваЗаголовка.ИдентификаторНастроек);
	СброситьСортировку(Настройки, СвойстваЗаголовка);
	
	Группировка = Настройки.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторГруппировки);
	Если ТипЗнч(Группировка) = Тип("НастройкиВложенногоОбъектаКомпоновкиДанных") Тогда
		ЭлементыСортировки = Группировка.Настройки.Порядок.Элементы;
	ИначеЕсли СвойстваЗаголовка.КоличествоРазделов = 1 Тогда 
		ЭлементыСортировки = Настройки.Порядок.Элементы;
	Иначе
		Раздел = Настройки.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторРаздела);
		Если ТипЗнч(Раздел) = Тип("ТаблицаКомпоновкиДанных") И Раздел.Строки.Количество() = 1 Тогда 
			ОсновнаяГруппировка = Раздел.Строки[0];
			ПолеГруппировки = ВариантыОтчетовСлужебныйКлиентСервер.ПолеОтчета(ОсновнаяГруппировка.ПоляГруппировки, СвойстваЗаголовка.Поле);
			Если СвойстваЗаголовка.Ресурс Или ПолеГруппировки <> Неопределено Тогда 
				Группировка = ОсновнаяГруппировка;
			КонецЕсли;
		КонецЕсли;
		ЭлементыСортировки = Группировка.Порядок.Элементы;
	КонецЕсли;
	
	ЭлементСортировки = ЭлементСортировкиРаздела(ЭлементыСортировки, СвойстваЗаголовка.Поле);
	
	Если ЭлементСортировки = Неопределено Тогда 
		
		Индекс = ИндексЭлементСортировкиРаздела(ЭлементыСортировки, СвойстваЗаголовка.Поле);
		ЭлементСортировки = ЭлементыСортировки.Вставить(Индекс, Тип("ЭлементПорядкаКомпоновкиДанных"));
		ЭлементСортировки.Поле = СвойстваЗаголовка.Поле;
		
	КонецЕсли;
	
	ЭлементСортировки.ТипУпорядочивания = ТипСортировкиРаздела(Команда);
	ЭлементСортировки.Использование = Истина;
	
	ОповеститьОЗавершенииКонтекстнойНастройки(Форма, ДействиеКоманды(Команда));
	
КонецПроцедуры

#КонецОбласти

#КонецОбласти

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

#Область ВставкаПоля

Процедура ВставитьПоле(Настройки, Настройки2, ВыбранноеПоле, Действие, СвойстваЗаголовка, РолиПолей)
	
	Группировка = Настройки.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторГруппировки);
	Группировка2 = Настройки2.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторГруппировки);
	
	ВставитьПолеВПоляГруппировки(Группировка, Группировка2, ВыбранноеПоле, СвойстваЗаголовка.Поле, Действие, РолиПолей);
	ВставитьПолеВГруппировкуРаздела(Группировка, Группировка2, ВыбранноеПоле, СвойстваЗаголовка.Поле, Действие, РолиПолей);
	
КонецПроцедуры

Процедура ВставитьПолеВПоляГруппировки(Группировка, Группировка2, ВыбранноеПоле, ТекущееПоле, Действие, РолиПолей)
	
	Если ВыбранноеПоле.Ресурс Тогда 
		Возврат;
	КонецЕсли;
	
	Поля2 = Группировка2.ПоляГруппировки;
	НайденноеТекущееПоле2 = ВариантыОтчетовСлужебныйКлиентСервер.ПолеОтчета(Поля2, ТекущееПоле);
	
	Если НайденноеТекущееПоле2 = Неопределено Тогда 
		Возврат;
	КонецЕсли;
	
	ТекущееПолеЯвляетсяПериодом = (РолиПолей.Периоды[ТекущееПоле] <> Неопределено);
	ВыбранноеПолеЯвляетсяПериодом = (РолиПолей.Периоды[ВыбранноеПоле.Поле] <> Неопределено);
	
	Если ТекущееПолеЯвляетсяПериодом И Не ВыбранноеПолеЯвляетсяПериодом
		Или Не ТекущееПолеЯвляетсяПериодом И ВыбранноеПолеЯвляетсяПериодом Тогда 
		
		Возврат;
	КонецЕсли;
	
	СкопироватьПоля(Группировка, Группировка2, "ПоляГруппировки");
	Поля = Группировка.ПоляГруппировки;
	
	НайденноеТекущееПоле = ВариантыОтчетовСлужебныйКлиентСервер.ПолеОтчета(Поля, ТекущееПоле);
	
	ИндексПоля = Поля.Элементы.Индекс(НайденноеТекущееПоле);
	
	Если Действие = "ВставитьПолеСправа" Тогда 
		ИндексПоля = ИндексПоля + 1;
	КонецЕсли;
	
	НайденноеПоле = ВариантыОтчетовСлужебныйКлиентСервер.ПолеОтчета(Поля, ВыбранноеПоле.Поле);
	ВставляемоеПоле = Неопределено;
	
	Если НайденноеПоле <> Неопределено Тогда 
		
		Если Поля.Элементы.Индекс(НайденноеПоле) = ИндексПоля Тогда 
			
			ВставляемоеПоле = НайденноеПоле;
			ВставляемоеПоле.Использование = Истина;
			
		Иначе
			Поля.Элементы.Удалить(НайденноеПоле);
		КонецЕсли;
		
	КонецЕсли;
	
	Если ВставляемоеПоле <> Неопределено Тогда 
		Возврат;
	КонецЕсли;
	
	ВставляемоеПоле = Поля.Элементы.Вставить(ИндексПоля, Тип("ПолеГруппировкиКомпоновкиДанных"));
	ЗаполнитьЗначенияСвойств(ВставляемоеПоле, ВыбранноеПоле);
	
КонецПроцедуры

Процедура ВставитьПолеВГруппировкуРаздела(Группировка, Группировка2, ВыбранноеПоле, ТекущееПоле, Действие, РолиПолей)
	
	Если ТипЗнч(Группировка) <> Тип("ГруппировкаКомпоновкиДанных")
		И ТипЗнч(Группировка) <> Тип("ГруппировкаТаблицыКомпоновкиДанных") Тогда 
		
		Возврат;
	КонецЕсли;
	
	СкопироватьПоля(Группировка, Группировка2, "Выбор");
	Поля = Группировка.Выбор;
	НайденноеТекущееПоле = ВариантыОтчетовСлужебныйКлиентСервер.ПолеОтчета(Поля, ТекущееПоле);
	
	Если НайденноеТекущееПоле = Неопределено Тогда 
		
		ИндексПоля = 0;
		
	Иначе
		
		ИндексПоля = Поля.Элементы.Индекс(НайденноеТекущееПоле);
		
		Если Действие = "ВставитьПолеСправа" Тогда 
			ИндексПоля = ИндексПоля + 1;
		КонецЕсли;
		
	КонецЕсли;
	
	НайденноеПоле = ВариантыОтчетовСлужебныйКлиентСервер.ПолеОтчета(Поля, ВыбранноеПоле.Поле, Ложь);
	ВставляемоеПоле = Неопределено;
	ЗаголовокПоля = ВыбранноеПоле.Заголовок;
	
	Если НайденноеПоле <> Неопределено Тогда 
		
		Если Поля.Элементы.Индекс(НайденноеПоле) = ИндексПоля Тогда 
			
			ВставляемоеПоле = НайденноеПоле;
			ВставляемоеПоле.Использование = Истина;
			
		Иначе
			
			ЗаголовокПоля = НайденноеПоле.Заголовок;
			Поля.Элементы.Удалить(НайденноеПоле);
			ИндексПоля = ИндексПоля - 1;
			
		КонецЕсли;
		
	КонецЕсли;
	
	Если ВставляемоеПоле = Неопределено Тогда 
		
		ВставляемоеПоле = Поля.Элементы.Вставить(ИндексПоля, Тип("ВыбранноеПолеКомпоновкиДанных"));
		ЗаполнитьЗначенияСвойств(ВставляемоеПоле, ВыбранноеПоле);
		ВставляемоеПоле.Заголовок = ЗаголовокПоля;
		
	КонецЕсли;
	
	УстановитьВыводРеквизитовГруппировкиОтдельно(Группировка);
	
	ВставитьПолеВГруппировкиРаздела(Группировка, Группировка2, ВыбранноеПоле, ТекущееПоле, Действие, РолиПолей);
	
КонецПроцедуры

Процедура ВставитьПолеВГруппировкиРаздела(Родитель, Родитель2, ВыбранноеПоле, ТекущееПоле, Действие, РолиПолей)
	
	Если Не ВыбранноеПоле.Ресурс Тогда 
		Возврат;
	КонецЕсли;
	
	Если ТипЗнч(Родитель) = Тип("ТаблицаКомпоновкиДанных") Тогда 
		Группировки = Родитель.Строки;
		Группировки2 = Родитель2.Строки;
	Иначе
		Группировки = Родитель.Структура;
		Группировки2 = Родитель2.Структура;
	КонецЕсли;
	
	Для НомерГруппировки = 1 По Группировки.Количество() Цикл 
		Группировка = Группировки[НомерГруппировки - 1];
		Группировка2 = Группировки2[НомерГруппировки - 1];
		ВставитьПолеВГруппировкуРаздела(Группировка, Группировка2, ВыбранноеПоле, ТекущееПоле, Действие, РолиПолей);
	КонецЦикла;
	
КонецПроцедуры

Процедура УстановитьВыводРеквизитовГруппировкиОтдельно(Группировка)
	
	Если ТипЗнч(Группировка) <> Тип("ГруппировкаКомпоновкиДанных")
		И Не ТипЗнч(Группировка) <> Тип("ГруппировкаТаблицыКомпоновкиДанных") Тогда 
		
		Возврат;
	КонецЕсли;
	
	ВыводРеквизитов = Группировка.ПараметрыВывода.Элементы.Найти("РасположениеРеквизитов");
	
	Если Не ВыводРеквизитов.Использование Тогда 
		
		ВыводРеквизитов.Значение = РасположениеРеквизитовКомпоновкиДанных.Отдельно;
		ВыводРеквизитов.Использование = Истина;
		
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти

#Область ВставкаГруппировки

// Параметры:
//  Действие - НастройкиКомпоновкиДанных
//  Действие - Строка
//  Поле - ПолеКомпоновкиДанных
//       - ДоступноеПолеКомпоновкиДанных
//  СвойстваЗаголовка - см. ВариантыОтчетовСлужебный.СтандартныеСвойстваЗаголовкаОтчета
//
Процедура ВставитьГруппировку(Настройки, Действие, Поле, СвойстваЗаголовка)
	
	Раздел = Настройки.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторРаздела);
	Группировка = Настройки.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторГруппировки);
	
	КоллекцияГруппировок = КоллекцияГруппировокРаздела(
		Раздел, Группировка, СвойстваЗаголовка.ИдентификаторГруппировки, Действие);
	
	ПеремещаемыеГруппировки = Новый Массив;
	
	Для Каждого Элемент Из КоллекцияГруппировок.Группировки Цикл 
		ПеремещаемыеГруппировки.Добавить(Элемент);
	КонецЦикла;
	
	Если ТипЗнч(КоллекцияГруппировок.Группировки) = Тип("КоллекцияЭлементовСтруктурыНастроекКомпоновкиДанных") Тогда 
		
		НоваяГруппировка = КоллекцияГруппировок.Группировки.Вставить(
			КоллекцияГруппировок.ИндексГруппировки, Тип("ГруппировкаКомпоновкиДанных")); // ГруппировкаКомпоновкиДанных
		
	Иначе
		
		НоваяГруппировка = КоллекцияГруппировок.Группировки.Вставить(КоллекцияГруппировок.ИндексГруппировки);
		
	КонецЕсли;
	
	НовоеПоле = НоваяГруппировка.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
	НовоеПоле.Поле = ?(ТипЗнч(Поле) = Тип("ПолеКомпоновкиДанных"), Поле, Поле.Поле);
	НовоеПоле.Использование = Истина;
	
	НоваяГруппировка.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
	НоваяГруппировка.Порядок.Элементы.Добавить(Тип("АвтоЭлементПорядкаКомпоновкиДанных"));
	
	Для Каждого Группировка Из ПеремещаемыеГруппировки Цикл 
		
		ПоискЭлементов = Новый Соответствие;
		ОтчетыКлиентСервер.СкопироватьРекурсивно(
			Настройки, Группировка, НоваяГруппировка.Структура, КоллекцияГруппировок.ИндексГруппировки, ПоискЭлементов);
		
		КоллекцияГруппировок.Группировки.Удалить(Группировка);
		
	КонецЦикла;
	
КонецПроцедуры

// Параметры:
//  Раздел - НастройкиКомпоновкиДанных
//         - НастройкиВложенногоОбъектаКомпоновкиДанных
//         - ГруппировкаКомпоновкиДанных
//         - КоллекцияЭлементовСтруктурыНастроекКомпоновкиДанных
//         - ТаблицаКомпоновкиДанных
//         - ГруппировкаТаблицыКомпоновкиДанных
//         - КоллекцияЭлементовСтруктурыТаблицыКомпоновкиДанных
//         - Неопределено
//  Группировка - НастройкиКомпоновкиДанных
//              - НастройкиВложенногоОбъектаКомпоновкиДанных
//              - ГруппировкаКомпоновкиДанных
//              - КоллекцияЭлементовСтруктурыНастроекКомпоновкиДанных
//              - ТаблицаКомпоновкиДанных
//              - ГруппировкаТаблицыКомпоновкиДанных
//              - КоллекцияЭлементовСтруктурыТаблицыКомпоновкиДанных
//              - Неопределено
//  ИдентификаторГруппировки - ИдентификаторКомпоновкиДанных
//  Действие - Строка
//
// Возвращаемое значение:
//  Структура:
//    * ИндексГруппировки - Число
//    * Группировки - КоллекцияЭлементовСтруктурыНастроекКомпоновкиДанных
//                  - КоллекцияЭлементовСтруктурыТаблицыКомпоновкиДанных
//
Функция КоллекцияГруппировокРаздела(Раздел, Группировка, ИдентификаторГруппировки, Действие)
	
	Коллекция = Новый Структура;
	Коллекция.Вставить("Группировки", Неопределено);
	Коллекция.Вставить("ИндексГруппировки", 0);
	
	Если Действие = "ВставитьГруппировкуНиже" Тогда 
		
		Коллекция.Группировки = Группировка.Структура;
		
		Возврат Коллекция;
		
	КонецЕсли;
	
	Родитель = Группировка.Родитель; // ГруппировкаКомпоновкиДанных, ГруппировкаТаблицыКомпоновкиДанных
	
	Если Родитель <> Раздел Тогда 
		
		Группировки = Родитель.Структура; // КоллекцияЭлементовСтруктурыНастроекКомпоновкиДанных, КоллекцияЭлементовСтруктурыТаблицыКомпоновкиДанных
		Коллекция.Группировки = Группировки;
		Коллекция.ИндексГруппировки = Группировки.Индекс(Группировка);
		
		Возврат Коллекция;
		
	КонецЕсли;
	
	Если ТипЗнч(Раздел) = Тип("ТаблицаКомпоновкиДанных") Тогда 
		
		Коллекция.Группировки = ?(СтрНайти(ИдентификаторГруппировки, "/row/") > 0, Раздел.Строки, Раздел.Колонки);
		
	Иначе
		
		Коллекция.Группировки = Раздел.Структура;
		
	КонецЕсли;
	
	Группировки = Коллекция.Группировки; // КоллекцияЭлементовСтруктурыНастроекКомпоновкиДанных, КоллекцияЭлементовСтруктурыТаблицыКомпоновкиДанных 
	Коллекция.ИндексГруппировки = Группировки.Индекс(Группировка);
	
	Возврат Коллекция;
	
КонецФункции

#КонецОбласти

#Область СкрытиеПоля

Функция ЭтоГруппировкаДетальныхЗаписей(Группировка2)
	
	Возврат Группировка2.ПоляГруппировки.Элементы.Количество() = 0;
	
КонецФункции

Процедура СкрытьВыбранноеПолеРаздела(Раздел, Раздел2, Поле)
	
	ГруппировкиРаздела = Новый Массив;
	ГруппировкиРаздела2 = Новый Массив;
	
	Если ТипЗнч(Раздел2) = Тип("ТаблицаКомпоновкиДанных") Тогда 
		
		ГруппировкиРаздела.Добавить(Раздел.Строки);
		ГруппировкиРаздела.Добавить(Раздел.Колонки);
		ГруппировкиРаздела2.Добавить(Раздел2.Строки);
		ГруппировкиРаздела2.Добавить(Раздел2.Колонки);
		
	Иначе
		
		ГруппировкиРаздела.Добавить(Раздел.Структура);
		ГруппировкиРаздела2.Добавить(Раздел2.Структура);
		СкрытьВыбранноеПолеГруппировки(Раздел, Раздел2, Поле);
		
	КонецЕсли;
	
	Для НомерГруппировкиРаздела = 1 По ГруппировкиРаздела2.Количество() Цикл
		Группировки = ГруппировкиРаздела[НомерГруппировкиРаздела - 1];
		Группировки2 = ГруппировкиРаздела2[НомерГруппировкиРаздела - 1];
		
		Для НомерГруппировки = 1 По Группировки2.Количество() Цикл
			Группировка = Группировки[НомерГруппировки - 1];
			Группировка2 = Группировки2[НомерГруппировки - 1];
			
			СкрытьВыбранноеПолеГруппировки(Группировка, Группировка2, Поле);
			СкрытьВыбранноеПолеРаздела(Группировка, Группировка2, Поле);
		КонецЦикла;
	КонецЦикла;
	
КонецПроцедуры

Процедура СкрытьВыбранноеПолеГруппировки(Группировка, Группировка2, Поле)
	
	Если ТипЗнч(Группировка2) <> Тип("ГруппировкаКомпоновкиДанных")
		И ТипЗнч(Группировка2) <> Тип("ГруппировкаТаблицыКомпоновкиДанных") Тогда 
		
		Возврат;
	КонецЕсли;
	
	ПолеНайдено = Ложь;
	СкрытьВыбранноеПолеВКоллекцииГруппировки(Группировка, Группировка2, Поле, "ПоляГруппировки", Истина, ПолеНайдено);
	СкрытьВыбранноеПолеВКоллекцииГруппировки(Группировка, Группировка2, Поле, "Выбор", ПолеНайдено);
	СкрытьВыбранноеПолеВКоллекцииГруппировки(Группировка, Группировка2, Поле, "Порядок", Истина);
	
КонецПроцедуры

Процедура СкрытьВыбранноеПолеВКоллекцииГруппировки(Группировка, Группировка2, Поле, ИмяКоллекции,
			БезКопирования = Ложь, ПолеНайдено = Ложь)
	
	ПолеОтчета = ПолеОтчета(Группировка, Группировка2, Поле, ИмяКоллекции, , БезКопирования);
	Если ПолеОтчета = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	ПолеНайдено = Истина;
	
	ПолеОтчета.Поле.Использование = Ложь;
	ПолеОтчета.Поле2.Использование = Ложь;
	
КонецПроцедуры

Функция ПолеОтчета(Группировка, Группировка2, Поле, ИмяКоллекции, ЗаголовокПоля = Неопределено, БезКопирования = Ложь)
	
	ПолеОтчета2 = ВариантыОтчетовСлужебныйКлиентСервер.ПолеОтчета(Группировка2[ИмяКоллекции], Поле,, ЗаголовокПоля);
	Если ПолеОтчета2 = Неопределено Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	ПолеОтчета = ВариантыОтчетовСлужебныйКлиентСервер.ПолеОтчета(Группировка[ИмяКоллекции], Поле,, ЗаголовокПоля);
	Если ПолеОтчета = Неопределено Тогда
		Если БезКопирования Тогда
			Возврат Неопределено;
		КонецЕсли;
		СкопироватьПоля(Группировка, Группировка2, ИмяКоллекции);
		ПолеОтчета = ВариантыОтчетовСлужебныйКлиентСервер.ПолеОтчета(Группировка[ИмяКоллекции], Поле,, ЗаголовокПоля);
	КонецЕсли;
	
	Возврат Новый Структура("Поле, Поле2", ПолеОтчета, ПолеОтчета2);
	
КонецФункции

Процедура СкопироватьПоля(Группировка, Группировка2, ИмяКоллекции)
	
	Группировка[ИмяКоллекции].Элементы.Очистить();
	Для Каждого ТекущееПоле2 Из Группировка2[ИмяКоллекции].Элементы Цикл
		НовоеПоле = Группировка[ИмяКоллекции].Элементы.Добавить(ТипЗнч(ТекущееПоле2));
		ЗаполнитьЗначенияСвойств(НовоеПоле, ТекущееПоле2);
	КонецЦикла;
	
КонецПроцедуры

Процедура СкрытьГруппировку(Настройки, Группировка, Настройки2, Группировка2, Поле)
	
	Поля = Группировка2.ПоляГруппировки;
	
	КоличествоИспользуемыхПолей = 0;
	
	Для Каждого Элемент Из Поля.Элементы Цикл 
		
		Если Элемент.Использование Тогда 
			КоличествоИспользуемыхПолей = КоличествоИспользуемыхПолей + 1;
		КонецЕсли;
		
	КонецЦикла;
	
	Если КоличествоИспользуемыхПолей > 0 Тогда 
		Возврат;
	КонецЕсли;
	
	Группировка.Использование = Ложь;
	Группировка2.Использование = Ложь;
	РодительскаяГруппировка = Группировка.Родитель;
	РодительскаяГруппировка2 = Группировка2.Родитель;
	
	Если ТипЗнч(РодительскаяГруппировка2) = Тип("ТаблицаКомпоновкиДанных") Тогда 
		
		ИдентификаторГруппировки2 = Настройки2.ПолучитьИдентификаторПоОбъекту(Группировка2);
		
		Если СтрНайти(ИдентификаторГруппировки2, "/row/") > 0 Тогда 
			Группировки = РодительскаяГруппировка.Строки;
			Группировки2 = РодительскаяГруппировка2.Строки;
		Иначе
			Группировки2 = РодительскаяГруппировка2.Колонки;
		КонецЕсли;
		
	Иначе
		Группировки = РодительскаяГруппировка.Структура;
		Группировки2 = РодительскаяГруппировка2.Структура;
	КонецЕсли;
	
	ИндексГруппировки = Группировки.Индекс(Группировка);
	ИндексГруппировки2 = Группировки2.Индекс(Группировка2);
	
	Для НомерДочернейГруппировки = 1 По Группировка2.Структура.Количество() Цикл
		ДочерняяГруппировка  = Группировка.Структура[НомерДочернейГруппировки - 1];
		ДочерняяГруппировка2 = Группировка2.Структура[НомерДочернейГруппировки - 1];
		
		Если Не ДочерняяГруппировка2.Использование Тогда 
			Продолжить;
		КонецЕсли;
		
		ОтчетыКлиентСервер.СкопироватьРекурсивно(Настройки, ДочерняяГруппировка, Группировки, ИндексГруппировки);
		ОтчетыКлиентСервер.СкопироватьРекурсивно(Настройки2, ДочерняяГруппировка2, Группировки2, ИндексГруппировки2);
		
		ДочерняяГруппировка.Использование = Ложь;
		ДочерняяГруппировка2.Использование = Ложь;
		
	КонецЦикла;
	
КонецПроцедуры

Функция КоличествоИспользуемыхПолей(Поля, Количество = Неопределено)
	
	Если Количество = Неопределено Тогда 
		Количество = 0;
	КонецЕсли;
	
	Для Каждого Элемент Из Поля.Элементы Цикл 
		
		Если ТипЗнч(Элемент) = Тип("ГруппаВыбранныхПолейКомпоновкиДанных") Тогда 
			
			КоличествоИспользуемыхПолей(Элемент, Количество);
			
		ИначеЕсли Элемент.Использование Тогда 
			
			Количество = Количество + 1;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат Количество;
	
КонецФункции

#КонецОбласти

#Область ПереименованиеПоля

Процедура ПослеВводаЗаголовкаПоляОтчета(Заголовок, ДополнительныеПараметры) Экспорт 
	
	Если ЗначениеЗаполнено(Заголовок) Тогда 
		ПереименоватьПоле(ДополнительныеПараметры.Форма, ДополнительныеПараметры.Команда, Заголовок);
	КонецЕсли;
	
КонецПроцедуры

Функция ТекущийЗаголовокПоляОтчета(Поле, ОписаниеПоля)
	
	ТекущийЗаголовок = "";
	
	Если Поле <> Неопределено
		И ЗначениеЗаполнено(Поле.Заголовок) Тогда 
		
		ТекущийЗаголовок = Поле.Заголовок;
		
	ИначеЕсли ОписаниеПоля <> Неопределено Тогда 
		
		ТекущийЗаголовок = ОписаниеПоля.Заголовок;
		
	ИначеЕсли Поле <> Неопределено Тогда 
		
		ТекущийЗаголовок = Строка(Поле);
		
	КонецЕсли;
	
	Возврат ТекущийЗаголовок;
	
КонецФункции

Процедура УстановитьЗаголовокПоляОтчета(Настройки, Поле, ОписаниеПоля, Заголовок)
	
	Если ОписаниеПоля <> Неопределено
		И Заголовок = ОписаниеПоля.Заголовок Тогда 
		
		Поле.Заголовок = "";
		
	Иначе
		
		Поле.Заголовок = Заголовок;
		
	КонецЕсли;
	
	Формула = ВариантыОтчетовСлужебныйКлиентСервер.ФормулаПоПутиКДанным(Настройки, Поле.Поле);
	
	Если ТипЗнч(Формула) = Тип("ПользовательскоеПолеВыражениеКомпоновкиДанных") Тогда 
		Формула.Заголовок = Заголовок;
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти

#Область Фильтрация

Процедура Фильтровать(Форма, ВидСравнения, СвойстваЗаголовка, ДанныеРасшифровки)
	
	Если ТипЗнч(ВидСравнения) = Тип("Строка") Тогда 
		
		ПоказатьРасширеннуюНастройкуФильтра(Форма, СвойстваЗаголовка);
		Возврат;
		
	КонецЕсли;
	
	ЭтоГруппировка = (ДанныеРасшифровки.Тип = ВариантыОтчетовСлужебныйКлиентСервер.ТипЭлементаРасшифровкиГруппировка());
	
	Настройки = ИспользуемыеНастройки(Форма, СвойстваЗаголовка.ИдентификаторНастроек);
	
	Фильтры = ВариантыОтчетовСлужебныйКлиентСервер.ФильтрыРазделаОтчета(Настройки, СвойстваЗаголовка, ЭтоГруппировка);
	Фильтр = ВариантыОтчетовСлужебныйКлиентСервер.ФильтрРазделаОтчета(Фильтры, СвойстваЗаголовка.Поле);
	
	Если Фильтр = Неопределено Тогда 
		
		Фильтр = Фильтры.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
		Фильтр.ЛевоеЗначение = СвойстваЗаголовка.Поле;
		
	КонецЕсли;
	
	Фильтр.ВидСравнения = ВидСравнения;
	Фильтр.ПравоеЗначение = ДанныеРасшифровки.Значение;
	Фильтр.Использование = Истина;
	
	ОповеститьОЗавершенииКонтекстнойНастройки(Форма, "Фильтровать", СвойстваЗаголовка.Текст);
	
КонецПроцедуры

#КонецОбласти

#Область Сортировка

Функция ТипСортировкиРазделаДоступен(Команда, СвойстваЗаголовка)
	
	ТекстПредупреждения = "";
	ШаблонПредупреждения = НСтр("ru = 'Поле ""%1"" уже отсортировано по %2'");
	
	Если СтрЗаканчиваетсяНа(ДействиеКоманды(Команда), "ПоВозрастанию")
		И Не СвойстваЗаголовка.СортироватьПоВозрастанию Тогда 
		
		ТекстПредупреждения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			ШаблонПредупреждения, СвойстваЗаголовка.Текст, НСтр("ru = 'возрастанию'"));
		
	ИначеЕсли СтрЗаканчиваетсяНа(ДействиеКоманды(Команда), "ПоУбыванию")
		И Не СвойстваЗаголовка.СортироватьПоУбыванию Тогда 
		
		ТекстПредупреждения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			ШаблонПредупреждения, СвойстваЗаголовка.Текст, НСтр("ru = 'убыванию'"));
		
	КонецЕсли;
	
	Если ЗначениеЗаполнено(ТекстПредупреждения) Тогда 
		
		ПоказатьПредупреждение(, ТекстПредупреждения);
		Возврат Ложь;
		
	КонецЕсли;
	
	Возврат Истина;
	
КонецФункции

Функция ТипСортировкиРаздела(Команда)
	
	Если СтрЗаканчиваетсяНа(ДействиеКоманды(Команда), "ПоВозрастанию") Тогда 
		
		Возврат НаправлениеСортировкиКомпоновкиДанных.Возр;
		
	КонецЕсли;
	
	Возврат НаправлениеСортировкиКомпоновкиДанных.Убыв;
	
КонецФункции

Функция ЭлементСортировкиРаздела(ЭлементыСортировки, Поле)
	
	ЭлементСортировки = Неопределено;
	
	Для Каждого Элемент Из ЭлементыСортировки Цикл 
		
		Если ТипЗнч(Элемент) <> Тип("АвтоЭлементПорядкаКомпоновкиДанных")
			И Элемент.Поле = Поле Тогда 
			
			ЭлементСортировки = Элемент;
			Прервать;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат ЭлементСортировки;
	
КонецФункции

Функция ИндексЭлементСортировкиРаздела(ЭлементыСортировки, Поле)
	
	Для Каждого Элемент Из ЭлементыСортировки Цикл 
		
		Если ТипЗнч(Элемент) = Тип("АвтоЭлементПорядкаКомпоновкиДанных") Тогда 
			Возврат ЭлементыСортировки.Индекс(Элемент);
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат ЭлементыСортировки.Количество();
	
КонецФункции

Процедура СброситьСортировку(Настройки, СвойстваЗаголовка, ЭлементыСтруктуры = Неопределено)
	
	Если ЭлементыСтруктуры = Неопределено Тогда 
		Настройки.ОчиститьПорядокЭлемента(Настройки);
		ЭлементыСтруктуры = Настройки.Структура;
	КонецЕсли;
		
	Для Каждого Элемент Из ЭлементыСтруктуры Цикл 
		
		Настройки.ОчиститьПорядокЭлемента(Элемент);
		ТипЭлемента = ТипЗнч(Элемент);
		
		Если ТипЭлемента = Тип("ТаблицаКомпоновкиДанных") Тогда 
			СброситьСортировку(Настройки, СвойстваЗаголовка, Элемент.Строки);
			СброситьСортировку(Настройки, СвойстваЗаголовка, Элемент.Колонки);
		ИначеЕсли ТипЭлемента = Тип("НастройкиВложенногоОбъектаКомпоновкиДанных") Тогда 
			СброситьСортировку(Элемент.Настройки, СвойстваЗаголовка);
		ИначеЕсли ТипЭлемента = Тип("ГруппировкаКомпоновкиДанных")
			Или ТипЭлемента = Тип("ГруппировкаТаблицыКомпоновкиДанных") Тогда 
			СброситьСортировку(Настройки, СвойстваЗаголовка, Элемент.Структура);
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

#КонецОбласти

#Область Оформление

#Область ОчисткаОформления

Процедура ОчиститьОформлениеГруппировокРазделаОтчета(Группировки, СвойстваЗаголовка)
	
	Для Каждого Группировка Из Группировки Цикл 
		ОчиститьОформлениеГруппировкиРазделаОтчета(Группировка, СвойстваЗаголовка);
	КонецЦикла;
	
КонецПроцедуры

Процедура ОчиститьОформлениеГруппировкиРазделаОтчета(Группировка, СвойстваЗаголовка)
	
	Если ТипЗнч(Группировка) = Тип("ТаблицаКомпоновкиДанных") Тогда 
		
		ОчиститьОформлениеГруппировокРазделаОтчета(Группировка.Строки, СвойстваЗаголовка);
		
	Иначе
		
		ОчиститьОформлениеГруппировкиОтчета(Группировка, СвойстваЗаголовка);
		
		ОчиститьОформлениеГруппировокРазделаОтчета(Группировка.Структура, СвойстваЗаголовка)
		
	КонецЕсли;
	
КонецПроцедуры

Процедура ОчиститьОформлениеГруппировкиОтчета(Группировка, СвойстваЗаголовка)
	
	Для Каждого ЭлементОформления Из Группировка.УсловноеОформление.Элементы Цикл 
		
		ОформляемыеПоля = ЭлементОформления.Поля.Элементы;
		
		ОформляемыеПоляПодходящие = Новый Массив;
		ОформляемыеПоляИспользуемые = Новый Массив;
		
		Для Каждого ОформляемоеПоле Из ОформляемыеПоля Цикл 
			
			Если ОформляемоеПоле.Поле = СвойстваЗаголовка.Поле Тогда 
				ОформляемыеПоляПодходящие.Добавить(ОформляемоеПоле);
			КонецЕсли;
			
			Если ОформляемоеПоле.Использование Тогда 
				ОформляемыеПоляИспользуемые.Добавить(ОформляемоеПоле);
			КонецЕсли;
			
		КонецЦикла;
		
		Если ОформляемыеПоляИспользуемые.Количество() = 1
			И ОформляемыеПоляИспользуемые[0].Поле = СвойстваЗаголовка.Поле Тогда 
			
			ОформляемыеПоляИспользуемые.Очистить();
			
		ИначеЕсли ОформляемыеПоляПодходящие.Количество() > 0 Тогда 
			
			ОформляемыеПоляПодходящие[0].Использование = Ложь;
			
		КонецЕсли;
		
		Если ОформляемыеПоляИспользуемые.Количество() = 0 Тогда 
			ЭлементОформления.Использование = Ложь;
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

#КонецОбласти

Процедура ОформитьЖелтым(Форма, Команда, СвойстваЗаголовка = Неопределено, Значение = Неопределено)
	
	Если СвойстваЗаголовка = Неопределено Тогда 
		СвойстваЗаголовка = СвойстваЗаголовкаОтчета(Форма);
	КонецЕсли;
	
	Если СвойстваЗаголовка = Неопределено Тогда 
		Возврат;
	КонецЕсли;
	
	ПараметрыРаскраски = ПараметрыРаскраскиРазделаОтчета(ДействиеКоманды(Команда));
	ПараметрыРаскраски.Условие.ЛевоеЗначение = СвойстваЗаголовка.Поле;
	ПараметрыРаскраски.Условие.ВидСравнения = ВидСравненияУсловияОформления(Значение);
	ПараметрыРаскраски.Условие.ПравоеЗначение = Значение;
	
	ЭлементыСтиля = СтандартныеПодсистемыКлиент.ЭлементыСтиля();
	
	Оформление = СтандартныйПараметрРаскраскиРазделаОтчета();
	Оформление.Параметр = "ЦветТекста";
	Оформление.Значение = ЭлементыСтиля.ЦветТекстаВнимание;
	
	ПараметрыРаскраски.Оформление.Добавить(Оформление);
	
	Оформление = СтандартныйПараметрРаскраскиРазделаОтчета();
	Оформление.Параметр = "ЦветФона";
	Оформление.Значение = ЭлементыСтиля.ЦветФонаВнимание;
	
	ПараметрыРаскраски.Оформление.Добавить(Оформление);
	ПараметрыРаскраски.Представление = НСтр("ru = 'Оформить желтым'");
	
	РаскраситьРазделОтчета(Форма, ПараметрыРаскраски, СвойстваЗаголовка);
	
	ОповеститьОЗавершенииКонтекстнойНастройки(Форма, ДействиеКоманды(Команда), СвойстваЗаголовка.Текст);
	
КонецПроцедуры

#Область РаскраскаГруппировкиОтчета

// Параметры:
//  Действие - Строка
//
// Возвращаемое значение:
//  Структура:
//    * Условие - Структура:
//        ** ЛевоеЗначение - ПолеКомпоновкиДанных
//        ** ВидСравнения - ВидСравненияКомпоновкиДанных
//        ** ПравоеЗначение - Неопределено
//    * Массив
//
Функция ПараметрыРаскраскиРазделаОтчета(Действие)
	
	Условие = Новый Структура;
	Условие.Вставить("ЛевоеЗначение", Неопределено);
	Условие.Вставить("ВидСравнения", ВидСравненияКомпоновкиДанных.Равно);
	Условие.Вставить("ПравоеЗначение", Неопределено);
	
	ПараметрыРаскраски = Новый Структура;
	ПараметрыРаскраски.Вставить("Условие", Условие);
	ПараметрыРаскраски.Вставить("Оформление", Новый Массив);
	ПараметрыРаскраски.Вставить("Представление", "");
	
	Возврат ПараметрыРаскраски;
	
КонецФункции

// Возвращаемое значение:
//  Структура:
//    * Параметр - Строка
//    * Значение - Неопределено
//
Функция СтандартныйПараметрРаскраскиРазделаОтчета()
	
	Параметр = Новый Структура;
	Параметр.Вставить("Параметр", "");
	Параметр.Вставить("Значение", Неопределено);
	
	Возврат Параметр;
	
КонецФункции

// Параметры:
//  Форма - ФормаКлиентскогоПриложения
//  ПараметрыРаскраски - см. ПараметрыРаскраскиРазделаОтчета
//  СвойстваЗаголовка - см. ВариантыОтчетовСлужебный.СтандартныеСвойстваЗаголовкаОтчета
//
Процедура РаскраситьРазделОтчета(Форма, ПараметрыРаскраски, СвойстваЗаголовка)
	
	Настройки = ИспользуемыеНастройки(Форма, СвойстваЗаголовка.ИдентификаторНастроек);
	Настройки2 = ИспользуемыеНастройки(Форма, СвойстваЗаголовка.ИдентификаторНастроек, Истина);
	Группировка = Настройки.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторГруппировки);
	Группировка2 = Настройки2.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторГруппировки);

	Если ТипЗнч(Группировка) = Тип("НастройкиВложенногоОбъектаКомпоновкиДанных") Тогда
		ПрименитьРаскраскуГруппировкиОтчета(Группировка.Настройки, Группировка2.Настройки, ПараметрыРаскраски, СвойстваЗаголовка);
	ИначеЕсли СвойстваЗаголовка.КоличествоРазделов = 1 Тогда 
		ПрименитьРаскраскуГруппировкиОтчета(Настройки, Настройки2, ПараметрыРаскраски, СвойстваЗаголовка);
	Иначе
		Раздел = Настройки.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторРаздела);
		Раздел2 = Настройки2.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторРаздела);
		Если ТипЗнч(Раздел) = Тип("ТаблицаКомпоновкиДанных") Тогда 
			РаскраситьГруппировкиРазделаОтчета(Раздел.Строки, Раздел2.Строки, ПараметрыРаскраски, СвойстваЗаголовка);
		Иначе
			РаскраситьГруппировкуРазделаОтчета(Раздел, Раздел2, ПараметрыРаскраски, СвойстваЗаголовка);
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

Процедура РаскраситьГруппировкиРазделаОтчета(Группировки, Группировки2, ПараметрыРаскраски, СвойстваЗаголовка)
	
	Для НомерГруппировки = 1 По Группировки.Количество() Цикл
		Группировка = Группировки[НомерГруппировки - 1];
		Группировка2 = Группировки2[НомерГруппировки - 1];
		РаскраситьГруппировкуРазделаОтчета(Группировка, Группировка2, ПараметрыРаскраски, СвойстваЗаголовка);
	КонецЦикла;
	
КонецПроцедуры

Процедура РаскраситьГруппировкуРазделаОтчета(Группировка, Группировка2, ПараметрыРаскраски, СвойстваЗаголовка)
	
	Если ТипЗнч(Группировка) = Тип("ТаблицаКомпоновкиДанных") Тогда 
		
		РаскраситьГруппировкиРазделаОтчета(Группировка.Строки, Группировка2.Строки, ПараметрыРаскраски, СвойстваЗаголовка);
		
	Иначе
		
		ПрименитьРаскраскуГруппировкиОтчета(Группировка, Группировка2, ПараметрыРаскраски, СвойстваЗаголовка);
		
		РаскраситьГруппировкиРазделаОтчета(Группировка.Структура, Группировка2.Структура, ПараметрыРаскраски, СвойстваЗаголовка)
		
	КонецЕсли;
	
КонецПроцедуры

Процедура ПрименитьРаскраскуГруппировкиОтчета(Группировка, Группировка2, ПараметрыРаскраски, СвойстваЗаголовка)
	
	ПолеОформления = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(ПараметрыРаскраски.Условие, "ЛевоеЗначение");
	
	ПараметрыРаскраскиПрименимы = ОформлениеПрименимоКГруппировке(Группировка2,
		ПолеОформления, СвойстваЗаголовка.Ресурс);
	
	Если ПараметрыРаскраскиПрименимы Тогда 
		
		Раскраска = РаскраскаГруппировкиОтчета(Группировка.УсловноеОформление, ПараметрыРаскраски);
		
		Если Раскраска = Неопределено Тогда 
			ДобавитьРаскраскуГруппировкиОтчета(Группировка.УсловноеОформление, ПараметрыРаскраски);
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

// Параметры:
//  Группировка - НастройкиКомпоновкиДанных
//              - НастройкиВложенногоОбъектаКомпоновкиДанных
//              - ГруппировкаКомпоновкиДанных
//              - ДиаграммаКомпоновкиДанных
//              - КоллекцияЭлементовСтруктурыДиаграммыКомпоновкиДанных
//              - ГруппировкаДиаграммыКомпоновкиДанных
//              - КоллекцияЭлементовСтруктурыТаблицыКомпоновкиДанных
//              - ГруппировкаТаблицыКомпоновкиДанных
//              - Неопределено
//  Поле - ПолеКомпоновкиДанных
//       - Неопределено
//  ЭтоРесурс - Булево
//
// Возвращаемое значение:
//   Булево
//
Функция ОформлениеПрименимоКГруппировке(Группировка, Поле, ЭтоРесурс)
	
	Если ТипЗнч(Группировка) <> Тип("ГруппировкаКомпоновкиДанных")
		И ТипЗнч(Группировка)<> Тип("ГруппировкаТаблицыКомпоновкиДанных") Тогда 
		
		Возврат Истина;
	КонецЕсли;
	
	ПоляГруппировки = Группировка.ПоляГруппировки;
	
	Возврат ЭтоРесурс
		Или Поле = Неопределено
		Или ПоляГруппировки.Элементы.Количество() = 0
		Или ВариантыОтчетовСлужебныйКлиентСервер.ПолеОтчета(ПоляГруппировки, Поле) <> Неопределено;
	
КонецФункции

Функция РаскраскаГруппировкиОтчета(УсловноеОформление, ПараметрыРаскраски)
	
	 Для Каждого Элемент Из УсловноеОформление.Элементы Цикл 
		
		Условие = УсловиеРаскраскиГруппировкиОтчета(Элемент.Отбор, ПараметрыРаскраски.Условие);
		
		Если Условие <> Неопределено Тогда 
			
			ОбновитьРаскраскуГруппировкиОтчета(Элемент, Условие, ПараметрыРаскраски);
			Возврат Элемент;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат Неопределено;
	
КонецФункции

Функция УсловиеРаскраскиГруппировкиОтчета(Отбор, Поиск)
	
	Условие = Неопределено;
	
	Для Каждого Элемент Из Отбор.Элементы Цикл 
		
		Если ТипЗнч(Элемент) = Тип("ЭлементОтбораКомпоновкиДанных")
			И Элемент.ЛевоеЗначение = Поиск.ЛевоеЗначение
			И Элемент.ВидСравнения = Поиск.ВидСравнения
			И Элемент.ПравоеЗначение = Поиск.ПравоеЗначение Тогда 
			
			Условие = Элемент;
			Прервать;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат Условие;
	
КонецФункции

Процедура ОбновитьРаскраскуГруппировкиОтчета(Оформление, Условие, ПараметрыРаскраски)
	
	Оформление.Использование = Истина;
	Условие.Использование = Истина;
	
	Оформление.Поля.Элементы.Очистить();
	
	Поле = Оформление.Поля.Элементы.Добавить();
	Поле.Поле = ПараметрыРаскраски.Условие.ЛевоеЗначение;
	Поле.Использование = Истина;
	
	СброситьОформлениеГруппировкиОтчета(Оформление);
	
	Для Каждого Параметр Из ПараметрыРаскраски.Оформление Цикл 
		Оформление.Оформление.УстановитьЗначениеПараметра(Параметр.Параметр, Параметр.Значение);
	КонецЦикла;
	
	УстановитьОбластьОформленияГруппировкиОтчета(Оформление);
	
КонецПроцедуры

Процедура ДобавитьРаскраскуГруппировкиОтчета(УсловноеОформление, ПараметрыРаскраски)
	
	Оформление = УсловноеОформление.Элементы.Добавить();
	
	Условие = Оформление.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
	ЗаполнитьЗначенияСвойств(Условие, ПараметрыРаскраски.Условие);
	Условие.Использование = Истина;
	
	Поле = Оформление.Поля.Элементы.Добавить();
	Поле.Поле = ПараметрыРаскраски.Условие.ЛевоеЗначение;
	Поле.Использование = Истина;
	
	Для Каждого Параметр Из ПараметрыРаскраски.Оформление Цикл 
		Оформление.Оформление.УстановитьЗначениеПараметра(Параметр.Параметр, Параметр.Значение);
	КонецЦикла;
	
	Оформление.ПредставлениеПользовательскойНастройки = ПараметрыРаскраски.Представление;
	
	УстановитьОбластьОформленияГруппировкиОтчета(Оформление);
	
КонецПроцедуры

Процедура СброситьОформлениеГруппировкиОтчета(ЭлементОформления, ТолькоПараметры = Истина)
	
	Для Каждого Элемент Из ЭлементОформления.Оформление.Элементы Цикл 
		Элемент.Использование = Ложь;
	КонецЦикла;
	
	Если ТолькоПараметры Тогда 
		Возврат;
	КонецЕсли;
	
	ЭлементОформления.Поля.Элементы.Очистить();
	ЭлементОформления.Отбор.Элементы.Очистить();
	
КонецПроцедуры

#КонецОбласти

#Область ИзменениеРазмера

Процедура ПослеВводаВысотыСтрокиОтчета(ВысотаСтроки, ДополнительныеПараметры) Экспорт 
	
	Если ЗначениеЗаполнено(ВысотаСтроки) Тогда 
		
		УстановитьВысотуСтроки(
			ДополнительныеПараметры.Форма,
			ДополнительныеПараметры.Команда,
			ДополнительныеПараметры.СвойстваЗаголовка,
			ВысотаСтроки,
			ДополнительныеПараметры.ПараметрыРазмераПоля);
		
	КонецЕсли;
	
КонецПроцедуры

Процедура ПослеВводаШириныКолонкиОтчета(ШиринаКолонки, ДополнительныеПараметры) Экспорт 
	
	Если ЗначениеЗаполнено(ШиринаКолонки) Тогда 
		
		УстановитьШиринуКолонки(
			ДополнительныеПараметры.Форма,
			ДополнительныеПараметры.Команда,
			ДополнительныеПараметры.СвойстваЗаголовка,
			ШиринаКолонки,
			ДополнительныеПараметры.ПараметрыРазмераПоля);
		
	КонецЕсли;
	
КонецПроцедуры

// Параметры:
//  Форма - ФормаКлиентскогоПриложения
//  СвойстваЗаголовка - см. ВариантыОтчетовСлужебный.СтандартныеСвойстваЗаголовкаОтчета
//  Ориентация - Строка
//
// Возвращаемое значение:
//  Структура:
//    * Размер - Число
//    * МаксимальныйРазмер - Число
//    * МинимальныйРазмер - Число
//    * Элемент - ЭлементУсловногоОформления
//    * Поле - ПолеКомпоновкиДанных
//
Функция ПараметрыРазмераПоляОтчета(Форма, СвойстваЗаголовка, Ориентация = "Высота") Экспорт 
	
	Если ТипЗнч(СвойстваЗаголовка.ИдентификаторНастроек) <> Тип("ИдентификаторКомпоновкиДанных") Тогда 
		Возврат СтандартныеПараметрыРазмераПоляОтчета();
	КонецЕсли;
	
	Настройки = ИспользуемыеНастройки(Форма, СвойстваЗаголовка.ИдентификаторНастроек);
	Группировка = Настройки.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторГруппировки);
	Если ТипЗнч(Группировка) = Тип("НастройкиВложенногоОбъектаКомпоновкиДанных") Тогда
		Оформление = Группировка.Настройки.УсловноеОформление;
	ИначеЕсли СвойстваЗаголовка.КоличествоРазделов = 1 Тогда 
		Оформление = Настройки.УсловноеОформление;
	Иначе
		Оформление = Группировка.УсловноеОформление;
	КонецЕсли;
	
	Для Каждого Элемент Из Оформление.Элементы Цикл 
		
		ПараметрыОформления = Элемент.Оформление.Элементы;
		
		Идентификаторы = ИдентификаторыПараметровРазмераПоля(Ориентация);
		МинимальныйРазмер = ПараметрыОформления.Найти(Идентификаторы.МинимальныйРазмер);
		МаксимальныйРазмер = ПараметрыОформления.Найти(Идентификаторы.МаксимальныйРазмер);
		
		Если МинимальныйРазмер.Использование
			Или МаксимальныйРазмер.Использование Тогда 
			
			Параметры = СтандартныеПараметрыРазмераПоляОтчета();
			Параметры.Поле = СвойстваЗаголовка.Поле;
			Параметры.Элемент = Элемент;
			Параметры.МинимальныйРазмер = МинимальныйРазмер;
			Параметры.МаксимальныйРазмер = МаксимальныйРазмер;
			Параметры.Размер = Макс(МинимальныйРазмер.Значение, МаксимальныйРазмер.Значение);
			
			Возврат Параметры;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат СтандартныеПараметрыРазмераПоляОтчета();
	
КонецФункции

Функция ИдентификаторыПараметровРазмераПоля(Ориентация)
	
	Идентификаторы = Новый Структура;
	
	Если Ориентация = "Высота" Тогда 
		
		Идентификаторы.Вставить("МинимальныйРазмер", "МинимальнаяВысота");
		Идентификаторы.Вставить("МаксимальныйРазмер", "МаксимальнаяВысота");
		
	Иначе
		
		Идентификаторы.Вставить("МинимальныйРазмер", "МинимальнаяШирина");
		Идентификаторы.Вставить("МаксимальныйРазмер", "МаксимальнаяШирина");
		
	КонецЕсли;
	
	Возврат Идентификаторы;
	
КонецФункции

Процедура ДобавитьПараметрыРазмераПоляОтчета(Форма, СвойстваЗаголовка, Размер, Ориентация = "Высота")
	
	Настройки = ИспользуемыеНастройки(Форма, СвойстваЗаголовка.ИдентификаторНастроек);
	Группировка = Настройки.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторГруппировки);
	Если ТипЗнч(Группировка) = Тип("НастройкиВложенногоОбъектаКомпоновкиДанных") Тогда
		Элемент = Группировка.Настройки.УсловноеОформление.Элементы.Добавить();
	ИначеЕсли СвойстваЗаголовка.КоличествоРазделов = 1 Тогда 
		Элемент = Настройки.УсловноеОформление.Элементы.Добавить();
	Иначе
		Элемент = Группировка.УсловноеОформление.Элементы.Добавить();
	КонецЕсли;
	
	ПараметрыОформления = Элемент.Оформление.Элементы;
	Идентификаторы = ИдентификаторыПараметровРазмераПоля(Ориентация);
	
	Параметры = СтандартныеПараметрыРазмераПоляОтчета(Размер);
	Параметры.Поле = СвойстваЗаголовка.Поле;
	Параметры.Элемент = Элемент;
	Параметры.МинимальныйРазмер = ПараметрыОформления.Найти(Идентификаторы.МинимальныйРазмер);
	Параметры.МаксимальныйРазмер = ПараметрыОформления.Найти(Идентификаторы.МаксимальныйРазмер);
	
	ОбновитьПараметрыРазмера(Параметры, Размер);
	
КонецПроцедуры

Процедура ОбновитьПараметрыРазмера(Параметры, Размер)
	
	Параметры.Элемент.Использование = Истина;
	
	Параметры.МинимальныйРазмер.Значение = Размер;
	Параметры.МинимальныйРазмер.Использование = Истина;
	
	Параметры.МаксимальныйРазмер.Значение = Размер;
	Параметры.МаксимальныйРазмер.Использование = Истина;
	
	ПроверитьИзменяемоеПоле(Параметры.Элемент.Поля, Параметры.Поле);
	УстановитьОбластьИзмененияРазмера(Параметры.Элемент);
	
КонецПроцедуры

// Параметры:
//  Размер - Число
//         - Неопределено
//
// Возвращаемое значение:
//  Структура:
//    * Размер - Число
//             - Неопределено
//    * МаксимальныйРазмер - Число
//    * МинимальныйРазмер - Число
//    * Элемент - ЭлементУсловногоОформления
//    * Поле - ПолеТабличногоДокумента
//
Функция СтандартныеПараметрыРазмераПоляОтчета(Размер = 0)
	
	Параметры = Новый Структура;
	Параметры.Вставить("Поле", Неопределено);
	Параметры.Вставить("Элемент", Неопределено);
	Параметры.Вставить("МинимальныйРазмер", Неопределено);
	Параметры.Вставить("МаксимальныйРазмер", Неопределено);
	Параметры.Вставить("Размер", Размер);
	
	Возврат Параметры;
	
КонецФункции

// Параметры:
//  Поля - ОформляемыеПоляКомпоновкиДанных
//  ПолеИскомое - ПолеКомпоновкиДанных
//
Процедура ПроверитьИзменяемоеПоле(Поля, ПолеИскомое)
	
	Поле = Неопределено;
	
	Для Каждого Элемент Из Поля.Элементы Цикл 
		
		Если Элемент.Поле = ПолеИскомое Тогда 
			
			Поле = Элемент;
			Прервать;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Если Поле = Неопределено Тогда 
		
		Поле = Поля.Элементы.Добавить();
		Поле.Поле = ПолеИскомое;
		
	КонецЕсли;
	
	Поле.Использование = Истина;
	
КонецПроцедуры

Процедура УстановитьОбластьИзмененияРазмера(Элемент)
	
	НеиспользуемыеОбласти = Новый Массив;
	НеиспользуемыеОбласти.Добавить("ИспользоватьВОбщемИтоге");
	НеиспользуемыеОбласти.Добавить("ИспользоватьВОтборе");
	НеиспользуемыеОбласти.Добавить("ИспользоватьВПараметрах");
	НеиспользуемыеОбласти.Добавить("ИспользоватьВЗаголовкеОбщегоИтога");
	Для Каждого Область Из НеиспользуемыеОбласти Цикл 
		Элемент[Область] = ИспользованиеУсловногоОформленияКомпоновкиДанных.НеИспользовать;
	КонецЦикла;
	
КонецПроцедуры

#КонецОбласти

#Область РасширенноеОформлениеГруппировкиОтчета

Функция ЭлементОформленияГруппировкиОтчета(Группировка, Поле)
	
	Оформление = Группировка.УсловноеОформление;
	
	Для Каждого ЭлементОформления Из Оформление.Элементы Цикл 
		
		Для Каждого ПолеОформления Из ЭлементОформления.Поля.Элементы Цикл 
			
			Если ПолеОформления.Поле = Поле Тогда 
				Возврат ЭлементОформления;
			КонецЕсли;
			
		КонецЦикла;
		
	КонецЦикла;
	
	Возврат Неопределено;
	
КонецФункции

Функция ИдентификаторЭлементаОформленияГруппировкиОтчета(Группировка, Поле)
	
	ЭлементОформления = ЭлементОформленияГруппировкиОтчета(Группировка, Поле);
	
	Если ЭлементОформления <> Неопределено Тогда 
		Возврат Группировка.УсловноеОформление.ПолучитьИдентификаторПоОбъекту(ЭлементОформления);
	КонецЕсли;
	
	Возврат Неопределено;
	
КонецФункции

Функция УсловиеОформленияГруппировкиОтчета(Поле, Значение)
	
	Если Значение = Неопределено Тогда 
		Возврат Неопределено;
	КонецЕсли;
	
	Условие = Новый Структура;
	Условие.Вставить("ЛевоеЗначение", Поле);
	Условие.Вставить("ВидСравнения", ВидСравненияУсловияОформления(Значение));
	Условие.Вставить("ПравоеЗначение", Значение);
	
	Возврат Условие;
	
КонецФункции

Функция ВидСравненияУсловияОформления(Значение)
	
	Если ТипЗнч(Значение) = Тип("СписокЗначений") Тогда 
		Возврат ВидСравненияКомпоновкиДанных.ВСписке;
	КонецЕсли;
	
	Возврат ВидСравненияКомпоновкиДанных.Равно;
	
КонецФункции

// Параметры:
//  Результат - Структура
//  ДополнительныеПараметры - Структура
//
Процедура ПослеИзмененияЭлементаОформленияГруппировкиОтчета(Результат, ДополнительныеПараметры) Экспорт 
	
	Если ТипЗнч(Результат) <> Тип("Структура") Тогда 
		Возврат;
	КонецЕсли;
	
	Форма = ДополнительныеПараметры.Форма;
	СвойстваЗаголовка = ДополнительныеПараметры.СвойстваЗаголовка;
	
	Настройки = ИспользуемыеНастройки(Форма);
	
	Если Результат.Свойство("ОписаниеФормул") Тогда 
		ДобавитьФормулы(Настройки, Настройки.ДоступныеПоляВыбора, Результат.ОписаниеФормул);
	КонецЕсли;
	
	ИспользуемыеНастройки = ИспользуемыеНастройки(Форма, СвойстваЗаголовка.ИдентификаторНастроек);
	ИспользуемыеНастройки2 = ИспользуемыеНастройки(Форма, СвойстваЗаголовка.ИдентификаторНастроек, Истина);
	Раздел = ИспользуемыеНастройки.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторРаздела);
	Раздел2 = ИспользуемыеНастройки2.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторРаздела);
	
	ОбразецОформления = Результат.ЭлементКД;
	Если ТипЗнч(Раздел) = Тип("НастройкиВложенногоОбъектаКомпоновкиДанных") Тогда
		ПрименитьОформлениеГруппировкиОтчета(Раздел.Настройки, Раздел2.Настройки, ОбразецОформления, СвойстваЗаголовка);
	ИначеЕсли СвойстваЗаголовка.КоличествоРазделов = 1 Тогда 
		ПрименитьОформлениеГруппировкиОтчета(ИспользуемыеНастройки, ИспользуемыеНастройки2, ОбразецОформления, СвойстваЗаголовка);
	ИначеЕсли ТипЗнч(Раздел) = Тип("ТаблицаКомпоновкиДанных") Тогда 
		ОформитьГруппировкиРазделаОтчета(Раздел.Строки, Раздел2.Строки, Результат.ЭлементКД, СвойстваЗаголовка);
	Иначе
		ОформитьГруппировкуРазделаОтчета(Раздел, Раздел2, Результат.ЭлементКД, СвойстваЗаголовка);
	КонецЕсли;
	
	ОповеститьОЗавершенииКонтекстнойНастройки(Форма, ДополнительныеПараметры.ДействиеКоманды);
	
КонецПроцедуры

Процедура ПрименитьОформлениеГруппировкиОтчета(Группировка, Группировка2, ОбразецОформления, СвойстваЗаголовка)
	
	ОформлениеПрименимоКГруппировке = ОформлениеПрименимоКГруппировке(Группировка2,
		СвойстваЗаголовка.Поле, СвойстваЗаголовка.Ресурс);
	
	Если ОформлениеПрименимоКГруппировке Тогда 
		
		Оформление = Группировка.УсловноеОформление;
		ЭлементОформления = ЭлементОформленияГруппировкиОтчета(Группировка, СвойстваЗаголовка.Поле);
		
		Если ЭлементОформления = Неопределено Тогда 
			ЭлементОформления = Оформление.Элементы.Добавить();
		Иначе
			СброситьОформлениеГруппировкиОтчета(ЭлементОформления, Ложь);
		КонецЕсли;
		
		ОтчетыКлиентСервер.ЗаполнитьСвойстваРекурсивно(Оформление, ЭлементОформления, ОбразецОформления);
		
		УстановитьОбластьОформленияГруппировкиОтчета(ЭлементОформления);
		
	КонецЕсли;
	
КонецПроцедуры

Процедура ОформитьГруппировкиРазделаОтчета(Группировки, Группировки2, ОбразецОформления, СвойстваЗаголовка)
	
	Для НомерГруппировки = 1 По Группировки.Количество() Цикл
		Группировка = Группировки[НомерГруппировки - 1];
		Группировка2 = Группировки2[НомерГруппировки - 1];
		ОформитьГруппировкуРазделаОтчета(Группировка, Группировка2, ОбразецОформления, СвойстваЗаголовка);
	КонецЦикла;
	
КонецПроцедуры

Процедура ОформитьГруппировкуРазделаОтчета(Группировка, Группировка2, ОбразецОформления, СвойстваЗаголовка)
	
	Если ТипЗнч(Группировка) = Тип("ТаблицаКомпоновкиДанных") Тогда 
		
		ОформитьГруппировкиРазделаОтчета(Группировка.Строки, Группировка2.Строки, ОбразецОформления, СвойстваЗаголовка);
		
	Иначе
		
		ПрименитьОформлениеГруппировкиОтчета(Группировка, Группировка2, ОбразецОформления, СвойстваЗаголовка);
		
		ОформитьГруппировкиРазделаОтчета(Группировка.Структура, Группировка2.Структура, ОбразецОформления, СвойстваЗаголовка);
		
	КонецЕсли;
	
КонецПроцедуры

Процедура УстановитьОбластьОформленияГруппировкиОтчета(ЭлементОформления)
	
	НеиспользуемыеОбласти = НеиспользуемыеОбластиОформления();
	
	Для Каждого Область Из НеиспользуемыеОбласти Цикл 
		ЭлементОформления[Область] = ИспользованиеУсловногоОформленияКомпоновкиДанных.НеИспользовать;
	КонецЦикла;
	
КонецПроцедуры

Функция НеиспользуемыеОбластиОформления()
	
	НеиспользуемыеОбласти = Новый Массив;
	НеиспользуемыеОбласти.Добавить("ИспользоватьВЗаголовке");
	НеиспользуемыеОбласти.Добавить("ИспользоватьВЗаголовкеПолей");
	НеиспользуемыеОбласти.Добавить("ИспользоватьВОбщемИтоге");
	НеиспользуемыеОбласти.Добавить("ИспользоватьВОтборе");
	НеиспользуемыеОбласти.Добавить("ИспользоватьВПараметрах");
	НеиспользуемыеОбласти.Добавить("ИспользоватьВЗаголовкеПолейРесурсов");
	НеиспользуемыеОбласти.Добавить("ИспользоватьВЗаголовкеОбщегоИтога");
	НеиспользуемыеОбласти.Добавить("ИспользоватьВЗаголовкеПолейРесурсовОбщегоИтога");
	
	Возврат НеиспользуемыеОбласти;
	
КонецФункции

#КонецОбласти

#КонецОбласти

#Область ВыборПоля

Процедура ВыбратьПолеОтчета(Форма, Действие, ИмяКоллекции, Обработчик = Неопределено,
	Поле = Неопределено, ИдентификаторУзлаНастроек = Неопределено)
	
	Если Обработчик = Неопределено Тогда 
		Обработчик = ОбработчикВыбораПоляОтчета(Форма, Действие);
	КонецЕсли;
	
	ПараметрыВыбора = Новый Структура;
	ПараметрыВыбора.Вставить("НастройкиОтчета", Форма.НастройкиОтчета);
	ПараметрыВыбора.Вставить("КомпоновщикНастроек", КомпоновщикНастроекОтчета(Форма));
	ПараметрыВыбора.Вставить("Режим", ИмяКоллекции);
	ПараметрыВыбора.Вставить("ПолеКД", Поле);
	ПараметрыВыбора.Вставить("ИдентификаторЭлементаСтруктурыНастроек",
		ИдентификаторЭлементаСтруктурыНастроек(Форма, ИдентификаторУзлаНастроек));
	
	ОткрытьФорму(
		"ХранилищеНастроек.ХранилищеВариантовОтчетов.Форма.ВыборПоляОтчета",
		ПараметрыВыбора, Форма, Форма.УникальныйИдентификатор,,, Обработчик);
	
КонецПроцедуры

Процедура ВыбратьПолеОтчетаИзМеню(Форма, Команда, ИмяКоллекции = "ВыбранныеПоля")
	
	Если Не ДействиеДоступно(Форма, Команда) Тогда 
		Возврат;
	КонецЕсли;
	
	Обработчик = ОбработчикВыбораПоляОтчета(Форма, ДействиеКоманды(Команда));
	УточнитьИмяКоллекции(ИмяКоллекции, Обработчик);
	
	ПоляОтчета = ПоляОтчета(Форма, Команда, ИмяКоллекции);
	
	Если ПоляОтчета = Неопределено Тогда 
		Возврат;
	КонецЕсли;
	
	Если ПоляОтчета.Количество() > 20
		Или ПоляОтчета.Количество() = 1
		И ПоляОтчета.НайтиПоЗначению("Еще") <> Неопределено Тогда 
		
		ВыбратьПолеОтчета(Форма, ДействиеКоманды(Команда), ИмяКоллекции, Обработчик);
		Возврат;
		
	КонецЕсли;
	
	Форма.ПоказатьВыборИзМеню(Обработчик, ПоляОтчета, Форма.ТекущийЭлемент);
	
КонецПроцедуры

// Параметры:
//  Форма - ФормаКлиентскогоПриложения
//  Действие - Строка
//
// Возвращаемое значение:
//  ОписаниеОповещения
//
Функция ОбработчикВыбораПоляОтчета(Форма, Действие)
	
	ПараметрыОбработчика = Новый Структура;
	ПараметрыОбработчика.Вставить("Форма", Форма);
	ПараметрыОбработчика.Вставить("Действие", Действие);
	ПараметрыОбработчика.Вставить("СвойстваЗаголовка", СвойстваЗаголовкаОтчета(Форма));
	
	Возврат Новый ОписаниеОповещения("ПослеВыбораПоля", Форма, ПараметрыОбработчика);
	
КонецФункции

// Параметры:
//  ВыбранноеПоле - ЭлементСпискаЗначений
//                - ВыбранноеПолеКомпоновкиДанных
//  ДополнительныеПараметры - Структура:
//    * Форма - ФормаКлиентскогоПриложения
//    * Действие - Строка
//    * СвойстваЗаголовка - см. СвойстваЗаголовкаОтчета
//
Процедура ПослеВыбораПоля(ВыбранноеПоле, ДополнительныеПараметры) Экспорт 
	
	Если ВыбранноеПоле = Неопределено Тогда 
		Возврат;
	КонецЕсли;
	
	Форма = ДополнительныеПараметры.Форма;
	Поле = ?(ТипЗнч(ВыбранноеПоле) = Тип("ЭлементСпискаЗначений"), ВыбранноеПоле.Значение, ВыбранноеПоле);
	
	Если Поле = "Еще" Тогда 
		
		ВыбратьПолеОтчета(Форма, ДополнительныеПараметры.Действие, ДополнительныеПараметры.ИмяКоллекции);
		Возврат;
		
	КонецЕсли;
	
	СвойстваЗаголовка = ДополнительныеПараметры.СвойстваЗаголовка;
	
	Настройки = ИспользуемыеНастройки(Форма, СвойстваЗаголовка.ИдентификаторНастроек);
	Настройки2 = ИспользуемыеНастройки(Форма, СвойстваЗаголовка.ИдентификаторНастроек, Истина);
	Действие = ДополнительныеПараметры.Действие;
	РолиПолей = Форма.НастройкиОтчета.СвойстваРезультата.РолиПолей;
	
	Если СтрСравнить(Действие, "ВставитьПолеСлева") = 0 Или СтрСравнить(Действие, "ВставитьПолеСправа") = 0 Тогда
		
		ДобавитьФормулу(Настройки, Настройки.ДоступныеПоляВыбора, Поле);
		ВставитьПоле(Настройки, Настройки2, Поле, Действие, СвойстваЗаголовка, РолиПолей);
		
	ИначеЕсли СтрНачинаетсяС(Действие, "ВставитьГруппировку") Тогда 
		
		ДобавитьФормулу(Настройки, Настройки.ДоступныеПоляГруппировок, Поле);
		ВставитьГруппировку(Настройки, Действие, Поле, СвойстваЗаголовка);
		
	КонецЕсли;
	
	ОповеститьОЗавершенииКонтекстнойНастройки(Форма, Действие, СвойстваЗаголовка.Текст);
	
КонецПроцедуры

#КонецОбласти

#Область ПоляОтчета

Функция ПоляОтчета(Форма, Команда, ИмяКоллекции)
	
	ДоступныеПоля = ДоступныеПоляОтчета(КомпоновщикНастроекОтчета(Форма), ИмяКоллекции);
	ПоляОтчета = ОсновныеПоляОтчета(Форма.НастройкиОтчета.СвойстваРезультата, ДоступныеПоля);
	
	Если ПоляОтчета.Количество() = 0 Тогда 
		ДобавитьДоступныеПоляОтчета(ПоляОтчета, ДоступныеПоля);
	КонецЕсли;
	
	ИсключитьИспользуемыеПоляОтчета(ПоляОтчета, Форма, Команда);
	ИсключитьНедоступныеПоляОтчета(ПоляОтчета, Форма, Команда);
	
	СвойстваЗаголовка = СвойстваЗаголовкаОтчета(Форма);
	
	Если СвойстваЗаголовка = Неопределено Тогда 
		Возврат Неопределено;
	КонецЕсли;
	
	Если ПоляОтчета.НайтиПоЗначению("Еще") = Неопределено Тогда 
		ПоляОтчета.Добавить("Еще", НСтр("ru = 'Еще...'"));
	КонецЕсли;
	
	Возврат ПоляОтчета;
	
КонецФункции

Функция ОписаниеПоляОтчета(КомпоновщикНастроек, Поле, ИмяКоллекции = "Выбор")
	
	ДоступныеПоля = ДоступныеПоляОтчета(КомпоновщикНастроек, ИмяКоллекции);
	
	Возврат ДоступныеПоля.НайтиПоле(Поле);
	
КонецФункции

Функция ДоступныеПоляОтчета(КомпоновщикНастроек, ИмяКоллекции = "Выбор")
	
	Если ИмяКоллекции = "Отборы" Тогда 
		
		Возврат КомпоновщикНастроек.Настройки.ДоступныеПоляОтбора;
		
	ИначеЕсли ИмяКоллекции = "Сортировка" Тогда 
		
		Возврат КомпоновщикНастроек.Настройки.ДоступныеПоляПорядка;
		
	ИначеЕсли ИмяКоллекции = "ПоляГруппировки" Тогда 
		
		Возврат КомпоновщикНастроек.Настройки.ДоступныеПоляГруппировок;
		
	КонецЕсли;
	
	Возврат КомпоновщикНастроек.Настройки.ДоступныеПоляВыбора;
	
КонецФункции

Функция ОсновныеПоляОтчета(СвойстваРезультата, ДоступныеПоля)
	
	ОсновныеПоляИзДоступных = Новый СписокЗначений;
	
	ОсновныеПоля = СвойстваРезультата.ОсновныеПоля;
	
	Для Каждого Поле Из ОсновныеПоля Цикл 
		
		ДоступноеПоле = ДоступныеПоля.НайтиПоле(Новый ПолеКомпоновкиДанных(Поле));
		
		Если ДоступноеПоле <> Неопределено
			И ОсновныеПоляИзДоступных.НайтиПоЗначению(ДоступноеПоле) = Неопределено Тогда 
			
			ОсновныеПоляИзДоступных.Добавить(ДоступноеПоле, ДоступноеПоле.Заголовок,, КартинкаПоля(ДоступноеПоле.ТипЗначения));
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат ОсновныеПоляИзДоступных;
	
КонецФункции

Процедура ДобавитьДоступныеПоляОтчета(ПоляОтчета, ДоступныеПоля)
	
	Для Каждого ДоступноеПоле Из ДоступныеПоля.Элементы Цикл 
		
		Если Не ДоступноеПоле.Папка Тогда 
			ПоляОтчета.Добавить(ДоступноеПоле, ДоступноеПоле.Заголовок,, КартинкаПоля(ДоступноеПоле.ТипЗначения));
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

// Параметры:
//  ОсновныеПоля - СписокЗначений
//  Форма - ФормаКлиентскогоПриложения
//  Команда - КомандаФормы
//
Процедура ИсключитьИспользуемыеПоляОтчета(ОсновныеПоля, Форма, Команда)
	
	Владелец = Форма.ТекущийЭлемент;
	
	Если ТипЗнч(Владелец) <> Тип("КнопкаФормы")
		И (ТипЗнч(Владелец) <> Тип("ПолеФормы") Или Владелец.Вид <> ВидПоляФормы.ПолеТабличногоДокумента) Тогда 
		
		Возврат;
	КонецЕсли;
	
	Если ДействиеКоманды(Команда) <> "ВставитьПолеСлева"
		И ДействиеКоманды(Команда) <> "ВставитьПолеСправа" Тогда 
		
		Возврат;
	КонецЕсли;
	
	СвойстваЗаголовка = СвойстваЗаголовкаОтчета(Форма);
	ИспользуемыеПоля = ИспользуемыеПоляОтчета(
		СвойстваЗаголовка, Форма.НастройкиОтчета.СвойстваРезультата.ИндексПолей);
	
	Индекс = ОсновныеПоля.Количество() - 1;
	
	Пока Индекс >= 0 Цикл 
		
		ДоступноеПоле = ОсновныеПоля[Индекс].Значение;
		
		Если ИспользуемыеПоля[ДоступноеПоле.Поле] <> Неопределено Тогда 
			ОсновныеПоля.Удалить(Индекс);
		КонецЕсли;
		
		Индекс = Индекс - 1;
		
	КонецЦикла;
	
КонецПроцедуры

Функция ИспользуемыеПоляОтчета(СвойстваЗаголовка, ИндексПолей)
	
	ИндексПолейРаздела = ИндексПолей[СвойстваЗаголовка.ПорядокРаздела];
	ИндексПолейГруппировки = ИндексПолейРаздела[СвойстваЗаголовка.ПорядокГруппировки];
	
	Возврат ИндексПолейГруппировки;
	
КонецФункции

Функция КартинкаПоля(ТипЗначенияПоля)
	
	ДоступныеТипы = ТипЗначенияПоля.Типы();
	
	Если ДоступныеТипы.Количество() = 0 Тогда 
		Возврат БиблиотекаКартинок.Пустая;
	КонецЕсли;
	
	Если ДоступныеТипы.Количество() > 1 Тогда 
		Возврат БиблиотекаКартинок.ТипСоставнойОсновной;
	КонецЕсли;
	
	Если ТипЗначенияПоля.СодержитТип(Тип("Число")) Тогда 
		Возврат БиблиотекаКартинок.ТипЧисло;
	КонецЕсли;
	
	Если ТипЗначенияПоля.СодержитТип(Тип("Строка")) Тогда 
		Возврат БиблиотекаКартинок.ТипСтрока;
	КонецЕсли;
	
	Если ТипЗначенияПоля.СодержитТип(Тип("Дата")) Тогда 
		Возврат БиблиотекаКартинок.ТипДата;
	КонецЕсли;
	
	Если ТипЗначенияПоля.СодержитТип(Тип("Булево")) Тогда 
		Возврат БиблиотекаКартинок.ТипБулево;
	КонецЕсли;
	
	Если ТипЗначенияПоля.СодержитТип(Тип("УникальныйИдентификатор")) Тогда 
		Возврат БиблиотекаКартинок.ТипИдентификатор;
	КонецЕсли;
	
	Возврат БиблиотекаКартинок.ТипСсылка;
	
КонецФункции

// Параметры:
//  ОсновныеПоля - СписокЗначений
//  Форма - ФормаКлиентскогоПриложения
//  Команда - КомандаФормы
//
Процедура ИсключитьНедоступныеПоляОтчета(ОсновныеПоля, Форма, Команда)
	
	Владелец = Форма.ТекущийЭлемент;
	
	Если ТипЗнч(Владелец) <> Тип("КнопкаФормы")
		И (ТипЗнч(Владелец) <> Тип("ПолеФормы") Или Владелец.Вид <> ВидПоляФормы.ПолеТабличногоДокумента) Тогда 
		
		Возврат;
	КонецЕсли;
	
	Если ДействиеКоманды(Команда) <> "ВставитьПолеСлева"
		И ДействиеКоманды(Команда) <> "ВставитьПолеСправа" Тогда 
		
		Возврат;
	КонецЕсли;
	
	СвойстваЗаголовка = СвойстваЗаголовкаОтчета(Форма);
	РолиПолей = Форма.НастройкиОтчета.СвойстваРезультата.РолиПолей;
	
	Индекс = ОсновныеПоля.Количество() - 1;
	
	Пока Индекс >= 0 Цикл 
		
		ДоступноеПоле = ОсновныеПоля[Индекс].Значение;
		
		Если СвойстваЗаголовка.Ресурс
			И Не ДоступноеПоле.Ресурс Тогда 
			
			ОсновныеПоля.Удалить(Индекс);
			
		ИначеЕсли СвойстваЗаголовка.Период
			И РолиПолей.Периоды[ДоступноеПоле.Поле] = Неопределено Тогда 
			
			ОсновныеПоля.Удалить(Индекс);
			
		ИначеЕсли Не СвойстваЗаголовка.Период
			И РолиПолей.Периоды[ДоступноеПоле.Поле] <> Неопределено Тогда 
			
			ОсновныеПоля.Удалить(Индекс);
			
		ИначеЕсли СвойстваЗаголовка.ИспользуетсяВПоляхГруппировки
			И СвойстваЗаголовка.ПереместитьПолеВправо
			И ДействиеКоманды(Команда) = "ВставитьПолеСправа"
			И ДоступноеПоле.Ресурс Тогда 
			
			ОсновныеПоля.Удалить(Индекс);
			
		ИначеЕсли СвойстваЗаголовка.ИспользуетсяВПоляхГруппировки
			И ДействиеКоманды(Команда) = "ВставитьПолеСлева"
			И ДоступноеПоле.Ресурс Тогда 
			
			ОсновныеПоля.Удалить(Индекс);
			
		КонецЕсли;
		
		Индекс = Индекс - 1;
		
	КонецЦикла;
	
КонецПроцедуры

#Область ПеремещениеПоля

Процедура ПереместитьПолеГоризонтально(Форма, Команда)
	
	Если Не ДействиеДоступно(Форма, Команда) Тогда 
		Возврат;
	КонецЕсли;
	
	СвойстваЗаголовка = СвойстваЗаголовкаОтчета(Форма);
	
	Настройки = ИспользуемыеНастройки(Форма, СвойстваЗаголовка.ИдентификаторНастроек);
	Настройки2 = ИспользуемыеНастройки(Форма, СвойстваЗаголовка.ИдентификаторНастроек, Истина);
	Группировка = Настройки.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторГруппировки);
	Группировка2 = Настройки2.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторГруппировки);
	
	Если Группировка = Неопределено ИЛИ Группировка2 = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	СкопироватьПоля(Группировка, Группировка2, "Выбор");
	
	Поля = Группировка.Выбор;
	ПереместитьРесурсыВКонец(Поля);
	ТекущееПоле = ВариантыОтчетовСлужебныйКлиентСервер.ПолеОтчета(Поля, СвойстваЗаголовка.Поле);
	
	ИсходныйИндексПоля = Поля.Элементы.Индекс(ТекущееПоле);
	
	Если ДействиеКоманды(Команда) = "ПереместитьПолеВлево" Тогда 
		
		НаправлениеСдвига = -1
		
	ИначеЕсли ДействиеКоманды(Команда) = "ПереместитьПолеВправо" Тогда 
		
		НаправлениеСдвига = 1
		
	КонецЕсли;
	
	КонечныйИндексПоля = ИсходныйИндексПоля + НаправлениеСдвига;
	
	Если КонечныйИндексПоля >= 0 Тогда 
	
		СоседнееПоле = Поля.Элементы[КонечныйИндексПоля];
		
		Пока КонечныйИндексПоля > 0 И Не СоседнееПоле.Использование Цикл 
			
			КонечныйИндексПоля = КонечныйИндексПоля + НаправлениеСдвига;
			СоседнееПоле = Поля.Элементы[КонечныйИндексПоля];
			
		КонецЦикла;
		
	КонецЕсли;
	
	Поля.Элементы.Сдвинуть(ТекущееПоле, КонечныйИндексПоля - ИсходныйИндексПоля);
	
	Если Не ЭтоГруппировкаДетальныхЗаписей(Группировка2) Тогда
		СкопироватьПорядокПолей(Группировка.ПоляГруппировки, Поля);
	КонецЕсли;
	
	ОповеститьОЗавершенииКонтекстнойНастройки(Форма, ДействиеКоманды(Команда), СвойстваЗаголовка.Текст);
	
КонецПроцедуры

Процедура ПереместитьРесурсыВКонец(Поля)
	
	Ресурсы = Новый Соответствие;
	Для Каждого ДоступноеПоле Из Поля.ДоступныеПоляВыбора.Элементы Цикл
		Если ДоступноеПоле.Ресурс Тогда
			Ресурсы.Вставить(ДоступноеПоле.Поле, Истина);
		КонецЕсли;
	КонецЦикла;
	
	Индекс = Поля.Элементы.Количество();
	ИндексПоследнегоРесурса = Индекс;
	Пока Индекс > 0 Цикл
		Индекс = Индекс - 1;
		ТекущийЭлемент = Поля.Элементы[Индекс];
		Если Ресурсы.Получить(ТекущийЭлемент.Поле) = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		Сдвиг = ИндексПоследнегоРесурса - Индекс - 1;
		ИндексПоследнегоРесурса = Индекс + Сдвиг;
		Если Сдвиг > 0 Тогда
			Поля.Элементы.Сдвинуть(ТекущийЭлемент, Сдвиг);
		КонецЕсли;
	КонецЦикла;
	
КонецПроцедуры

Процедура СкопироватьПорядокПолей(ПоляГруппировки, ПоляВыбора)
	
	Индекс = 0;
	Для Каждого ПолеВыбора Из ПоляВыбора.Элементы Цикл
		Для ТекущийИндекс = Индекс По ПоляГруппировки.Элементы.Количество() - 1 Цикл
			ПолеГруппировки = ПоляГруппировки.Элементы[ТекущийИндекс];
			Если ПолеГруппировки.Поле = ПолеВыбора.Поле Тогда
				Сдвиг = Индекс - ПоляГруппировки.Элементы.Индекс(ПолеГруппировки);
				ПоляГруппировки.Элементы.Сдвинуть(ПолеГруппировки, Сдвиг);
				Индекс = Индекс + 1;
				Прервать;
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;
	
КонецПроцедуры

Процедура ПереместитьПолеВертикально(Форма, Команда, Ответ = Неопределено)
	
	Если Не ДействиеДоступно(Форма, Команда) Тогда 
		Возврат;
	КонецЕсли;
	
	СвойстваЗаголовка = СвойстваЗаголовкаОтчета(Форма);
	
	Настройки = ИспользуемыеНастройки(Форма, СвойстваЗаголовка.ИдентификаторНастроек);
	Настройки2 = ИспользуемыеНастройки(Форма, СвойстваЗаголовка.ИдентификаторНастроек, Истина);
	Группировка  = Настройки.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторГруппировки);
	Группировка2 = Настройки2.ПолучитьОбъектПоИдентификатору(СвойстваЗаголовка.ИдентификаторГруппировки);
	СкопироватьПоля(Группировка, Группировка2, "ПоляГруппировки");
	СкопироватьПоля(Группировка, Группировка2, "Выбор");
	ПереместитьРесурсыВКонец(Группировка.Выбор);
	СкопироватьПорядокПолей(Группировка.ПоляГруппировки, Группировка.Выбор);
	
	ПолеГруппировки = ВариантыОтчетовСлужебныйКлиентСервер.ПолеОтчета(
		Группировка.ПоляГруппировки, СвойстваЗаголовка.Поле);
	
	ВыбранноеПоле = ВариантыОтчетовСлужебныйКлиентСервер.ПолеОтчета(
		Группировка.Выбор, СвойстваЗаголовка.Поле,, СвойстваЗаголовка.Текст);
	
	СоседняяГруппировка = СоседняяГруппировка(Форма, Команда, Настройки, СвойстваЗаголовка.ПорядокГруппировки);
	
	Если СоседняяГруппировка = Неопределено Тогда 
		Возврат;
	КонецЕсли;
	
	СоседняяГруппировка2 = СоседняяГруппировка(Форма, Команда, Настройки2, СвойстваЗаголовка.ПорядокГруппировки);
	СкопироватьПоля(СоседняяГруппировка, СоседняяГруппировка2, "ПоляГруппировки");
	СкопироватьПоля(СоседняяГруппировка, СоседняяГруппировка2, "Выбор");
	ПереместитьРесурсыВКонец(СоседняяГруппировка.Выбор);
	СкопироватьПорядокПолей(СоседняяГруппировка.ПоляГруппировки, СоседняяГруппировка.Выбор);
	
	ИсходныйИндексПоля = Группировка.Выбор.Элементы.Индекс(ВыбранноеПоле);
	
	Поля = СоседняяГруппировка.Выбор;
	ПараметрыПеремещения = Новый Структура("Форма, Команда, Ответ", Форма, Команда, Ответ);
	ИндексПоля = ИндексВыбранногоПоля(ИсходныйИндексПоля, Поля, СвойстваЗаголовка.Поле, ПараметрыПеремещения);
	
	Если ИндексПоля = Неопределено Тогда 
		Возврат;
	КонецЕсли;
	
	СоседнееВыбранноеПоле = ВариантыОтчетовСлужебныйКлиентСервер.ПолеОтчета(Поля, СвойстваЗаголовка.Поле, Ложь);
	Если СоседнееВыбранноеПоле = Неопределено Тогда
		СоседнееВыбранноеПоле = Поля.Элементы.Вставить(ИндексПоля, Тип("ВыбранноеПолеКомпоновкиДанных"));
	Иначе
		Поля.Элементы.Сдвинуть(СоседнееВыбранноеПоле, ИндексПоля - Поля.Элементы.Индекс(СоседнееВыбранноеПоле));
	КонецЕсли;
	ЗаполнитьЗначенияСвойств(СоседнееВыбранноеПоле, ВыбранноеПоле);
	ПереместитьРесурсыВКонец(Поля);
	
	УстановитьВыводРеквизитовГруппировкиОтдельно(СоседняяГруппировка);
	
	Поля = СоседняяГруппировка.ПоляГруппировки;
	КоличествоПолей = Поля.Элементы.Количество();
	
	Если КоличествоПолей > 0 Тогда 
		СоседнееПолеГруппировки = ВариантыОтчетовСлужебныйКлиентСервер.ПолеОтчета(Поля, СвойстваЗаголовка.Поле, Ложь);
		Если СоседнееПолеГруппировки = Неопределено Тогда
			СоседнееПолеГруппировки = Поля.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
		КонецЕсли;
		ЗаполнитьЗначенияСвойств(СоседнееПолеГруппировки,
			?(ПолеГруппировки = Неопределено, ВыбранноеПоле, ПолеГруппировки));
		СкопироватьПорядокПолей(Поля, СоседняяГруппировка.Выбор);
	КонецЕсли;
	
	Если ПолеГруппировки <> Неопределено Тогда 
		Группировка.ПоляГруппировки.Элементы.Удалить(ПолеГруппировки);
	КонецЕсли;
	
	Если ВыбранноеПоле <> Неопределено Тогда 
		
		Если Группировка.ПоляГруппировки.Элементы.Количество() = 0 Тогда 
			
			ВыбранноеПоле.Использование = Ложь;
			
			Если КоличествоИспользуемыхПолей(Группировка.Выбор) = 0 Тогда 
				СкрытьГруппировку(Настройки, Группировка, Настройки, Группировка, СвойстваЗаголовка.Поле);
			КонецЕсли;
			
		Иначе
			Группировка.Выбор.Элементы.Удалить(ВыбранноеПоле);
		КонецЕсли;
		
	КонецЕсли;
	
	ОповеститьОЗавершенииКонтекстнойНастройки(Форма, ДействиеКоманды(Команда), СвойстваЗаголовка.Текст);
	
КонецПроцедуры

Функция СоседняяГруппировка(Форма, Команда, Настройки, ПорядокГруппировки)
	
	Заголовки = ЗаголовкиОтчета(Форма);
	МинимальныйПорядокГруппировки = 0;
	МаксимальныйПорядокГруппировки = 0;
	
	Для Каждого Свойства Из Заголовки Цикл
		Если МаксимальныйПорядокГруппировки < Свойства.Значение.ПорядокГруппировки Тогда
			МаксимальныйПорядокГруппировки = Свойства.Значение.ПорядокГруппировки;
		КонецЕсли;
		Если МинимальныйПорядокГруппировки = 0
		 Или МинимальныйПорядокГруппировки > Свойства.Значение.ПорядокГруппировки Тогда
			МинимальныйПорядокГруппировки = Свойства.Значение.ПорядокГруппировки;
		КонецЕсли;
	КонецЦикла;
	
	Если Не ЗначениеЗаполнено(МинимальныйПорядокГруппировки) Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	Сдвиг = 0;
	Пока Истина Цикл
		Сдвиг = Сдвиг + 1;
		Если ДействиеКоманды(Команда) = "ПереместитьПолеВыше" Тогда 
			ПорядокСоседнейГруппировки = ПорядокГруппировки - Сдвиг;
		Иначе
			ПорядокСоседнейГруппировки = ПорядокГруппировки + Сдвиг;
		КонецЕсли;
		Если ПорядокСоседнейГруппировки < МинимальныйПорядокГруппировки
		 Или ПорядокСоседнейГруппировки > МаксимальныйПорядокГруппировки Тогда
			Прервать;
		КонецЕсли;
		
		Для Каждого Свойства Из Заголовки Цикл 
			Если Свойства.Значение.ПорядокГруппировки = ПорядокСоседнейГруппировки Тогда 
				Возврат Настройки.ПолучитьОбъектПоИдентификатору(Свойства.Значение.ИдентификаторГруппировки);
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;
	
	Возврат Неопределено;
	
КонецФункции

Функция ИндексВыбранногоПоля(ИсходныйИндексПоля, КонечнаяКоллекцияПолей, Поле, ПараметрыПеремещения)
	
	Граница = КонечнаяКоллекцияПолей.Элементы.Количество();
	
	НовоеПоле = ВариантыОтчетовСлужебныйКлиентСервер.ПолеОтчета(КонечнаяКоллекцияПолей, Поле);
	ДоступноеПоле = КонечнаяКоллекцияПолей.ДоступныеПоляВыбора.НайтиПоле(Поле);
	
	Если НовоеПоле <> Неопределено Тогда 
		
		Если ПараметрыПеремещения.Ответ = Неопределено Тогда 
			
			Обработчик = Новый ОписаниеОповещения("ПродолжитьПеремещениеПоляВертикально", ЭтотОбъект, ПараметрыПеремещения);
			
			ШаблонТекстаВопроса = НСтр("ru = 'Группировка уже содержит подобное поле - %1.
				|Удалить поле?'");
			
			ТекстВопроса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				ШаблонТекстаВопроса, ?(ДоступноеПоле = Неопределено, Поле, ДоступноеПоле.Заголовок));
			
			ПоказатьВопрос(Обработчик, ТекстВопроса, РежимДиалогаВопрос.ДаНетОтмена,, КодВозвратаДиалога.Да);
			
			Возврат Неопределено;
			
		ИначеЕсли ПараметрыПеремещения.Ответ = КодВозвратаДиалога.Да Тогда 
			
			КонечнаяКоллекцияПолей.Элементы.Удалить(НовоеПоле);
			
		КонецЕсли;
		
	КонецЕсли;
	
	Для Каждого Элемент Из КонечнаяКоллекцияПолей.Элементы Цикл 
		
		Если ТипЗнч(Элемент) = Тип("АвтоВыбранноеПолеКомпоновкиДанных")
			Или ТипЗнч(Элемент) = Тип("ГруппаВыбранныхПолейКомпоновкиДанных") Тогда 
			
			Продолжить;
		КонецЕсли;
		
		ДоступноеПоле = КонечнаяКоллекцияПолей.ДоступныеПоляВыбора.НайтиПоле(Элемент.Поле);
		
		Если ДоступноеПоле <> Неопределено
			И ДоступноеПоле.Ресурс Тогда 
			
			Граница = КонечнаяКоллекцияПолей.Элементы.Индекс(Элемент);
			Прервать;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат ?(ИсходныйИндексПоля < Граница, ИсходныйИндексПоля, Граница);
	
КонецФункции

Процедура ПродолжитьПеремещениеПоляВертикально(Ответ, ПараметрыПеремещения) Экспорт 
	
	Если Ответ = КодВозвратаДиалога.Да
		Или Ответ = КодВозвратаДиалога.Нет Тогда 
		
		ПереместитьПолеВертикально(ПараметрыПеремещения.Форма, ПараметрыПеремещения.Команда, Ответ);
		
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти

#КонецОбласти

#Область ОбработкаДополнительнойРасшифровки

// Параметры:
//  Форма - ФормаКлиентскогоПриложения
//  Область - ОбластьЯчеекТабличногоДокумента
//          - РисунокТабличногоДокумента
//  ИмяПоля - Строка
//
// Возвращаемое значение:
//  Структура:
//    * ЭтоЗаголовок - Булево
//
Функция СвойстваОбластиРасшифровки(Форма, Область, ИмяПоля)
	
	НастройкиОтчета = Форма.НастройкиОтчета; // см. ВариантыОтчетов.НастройкиФормыОтчета
	СвойстваРезультата = НастройкиОтчета.СвойстваРезультата; // см. ВариантыОтчетовСлужебный.СвойстваРезультатаОтчета
	СвойстваЗаголовка = СвойстваРезультата.Заголовки[Область.Имя]; // см. ВариантыОтчетовСлужебный.СтандартныеСвойстваЗаголовкаОтчета
	
	СвойстваОбласти = Новый Структура;
	СвойстваОбласти.Вставить("ЭтоЗаголовок", ТипЗнч(СвойстваЗаголовка) = Тип("Структура"));
	СвойстваОбласти.Вставить("СвойстваЗаголовка", СвойстваЗаголовка);
	
	Если СвойстваОбласти.ЭтоЗаголовок ИЛИ ТипЗнч(Область) = Тип("РисунокТабличногоДокумента") Тогда
		Возврат СвойстваОбласти;
	КонецЕсли;
	
	ПорядокРаздела = 0;
	ГраницаТекущегоРаздела = 0;
	
	Для Каждого Граница Из СвойстваРезультата.ГраницыРазделов Цикл 
		
		ПорядокРаздела = ПорядокРаздела + 1;
		
		Если Область.Верх >= ГраницаТекущегоРаздела
			И Область.Верх < Граница.Значение Тогда 
			
			Прервать;
		КонецЕсли;
		
		ГраницаТекущегоРаздела = Граница.Значение;
		
	КонецЦикла;
	
	Поле = Новый ПолеКомпоновкиДанных(ИмяПоля);
	
	Для Каждого Элемент Из СвойстваРезультата.Заголовки Цикл 
		
		СвойстваЗаголовка = Элемент.Значение;
		
		Если СвойстваЗаголовка.ПорядокРаздела = ПорядокРаздела
			И СвойстваЗаголовка.Поле = Поле
			И СвойстваЗаголовка.Лево = Область.Лево Тогда 
			
			СвойстваОбласти.СвойстваЗаголовка = СвойстваЗаголовка;
			Возврат СвойстваОбласти;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат СвойстваОбласти;
	
КонецФункции

#Область КонтекстноеМеню

Функция КонтекстноеМенюОбластиЗаголовка()
	
	КонтекстноеМеню = Новый СписокЗначений;
	КонтекстноеМеню.Добавить(ДействиеОбработкиРасшифровкиКомпоновкиДанных.ОткрытьЗначение, НСтр("ru = 'Открыть'"));
	
	// Фильтровать
	КонтекстноеМеню.Добавить("СнятьФильтр", НСтр("ru = 'Снять фильтр'"));
	КонтекстноеМеню.Добавить("Фильтровать", НСтр("ru = 'Фильтровать...'"),, БиблиотекаКартинок.ОтборКомпоновкиДанных);
	
	// Сортировать
	КонтекстноеМеню.Добавить(НаправлениеСортировкиКомпоновкиДанных.Возр, НСтр("ru = 'Сортировать по возрастанию'"),, БиблиотекаКартинок.СортироватьСтрокиПоВозрастанию);
	КонтекстноеМеню.Добавить(НаправлениеСортировкиКомпоновкиДанных.Убыв, НСтр("ru = 'Сортировать по убыванию'"),, БиблиотекаКартинок.СортироватьСтрокиПоУбыванию);
	
	// Оформить
	ПодменюОформления = Новый СписокЗначений;
	ПодменюОформления.Добавить("УстановитьВысотуСтроки", НСтр("ru = 'Высота строки...'"),, БиблиотекаКартинок.ВысотаСтроки);
	ПодменюОформления.Добавить("УстановитьШиринуКолонки", НСтр("ru = 'Ширина колонки...'"),, БиблиотекаКартинок.ШиринаКолонки);
	
	КонтекстноеМеню.Добавить(ПодменюОформления, НСтр("ru = 'Оформить'"),, БиблиотекаКартинок.УсловноеОформлениеКомпоновкиДанных);
	
	Возврат КонтекстноеМеню;
	
КонецФункции

Функция КонтекстноеМенюОбластиДанных(СвойстваЗаголовка, ДоступныеВидыСравнения)
	
	КонтекстноеМеню = Новый СписокЗначений;
	КонтекстноеМеню.Добавить(ДействиеОбработкиРасшифровкиКомпоновкиДанных.ОткрытьЗначение, НСтр("ru = 'Открыть'"));
	
	Если ТипЗнч(СвойстваЗаголовка) <> Тип("Структура") 
	   Или СвойстваЗаголовка.ПорядокРаздела <> 1 Тогда
		Возврат КонтекстноеМеню;
	КонецЕсли;
	
	КартинкиОформления = Новый Структура;
	КартинкиОформления.Вставить("ОформитьКрасным", БиблиотекаКартинок["ОформлениеКругКрасный"]);
	КартинкиОформления.Вставить("ОформитьЖелтым", БиблиотекаКартинок["ОформлениеКругЖелтый"]);
	КартинкиОформления.Вставить("ОформитьЗеленым", БиблиотекаКартинок["ОформлениеКругЗеленый"]);
	
	// Фильтровать
	УточнитьДоступныеВидыСравнения(ДоступныеВидыСравнения);
	КонтекстноеМеню.Добавить(ДоступныеВидыСравнения, НСтр("ru = 'Фильтровать'"),, БиблиотекаКартинок.ОтборКомпоновкиДанных);
	
	// Сортировать
	КонтекстноеМеню.Добавить(НаправлениеСортировкиКомпоновкиДанных.Возр, НСтр("ru = 'Сортировать по возрастанию'"),, БиблиотекаКартинок.СортироватьСтрокиПоВозрастанию);
	КонтекстноеМеню.Добавить(НаправлениеСортировкиКомпоновкиДанных.Убыв, НСтр("ru = 'Сортировать по убыванию'"),, БиблиотекаКартинок.СортироватьСтрокиПоУбыванию);
	
	// Оформить
	ПодменюОформления = Новый СписокЗначений;
	
	ПодменюОформления.Добавить("ОчиститьОформление", НСтр("ru = 'Очистить оформление'"));
	ПодменюОформления.Добавить("ОформитьКрасным", НСтр("ru = 'Красным'"),, КартинкиОформления.ОформитьКрасным);
	ПодменюОформления.Добавить("ОформитьЖелтым", НСтр("ru = 'Желтым'"),, КартинкиОформления.ОформитьЖелтым);
	ПодменюОформления.Добавить("ОформитьЗеленым", НСтр("ru = 'Зеленым'"),, КартинкиОформления.ОформитьЗеленым);
	ПодменюОформления.Добавить("ОформитьОтрицательные", НСтр("ru = 'Отрицательные красным'"));
	ПодменюОформления.Добавить("ОформитьПоложительные", НСтр("ru = 'Положительные зеленым'"));
	ПодменюОформления.Добавить("УстановитьВысотуСтроки", НСтр("ru = 'Высота строки...'"),, БиблиотекаКартинок.ВысотаСтроки);
	ПодменюОформления.Добавить("УстановитьШиринуКолонки", НСтр("ru = 'Ширина колонки...'"),, БиблиотекаКартинок.ШиринаКолонки);
	ПодменюОформления.Добавить("ОформитьЕще", НСтр("ru = 'Еще...'"));
	
	КонтекстноеМеню.Добавить(ПодменюОформления, НСтр("ru = 'Оформить'"),, БиблиотекаКартинок.УсловноеОформлениеКомпоновкиДанных);
	
	// Расшифровать
	КонтекстноеМеню.Добавить("РасшифроватьПоДетальнымЗаписям", НСтр("ru = 'Расшифровать по детальным записям'"));
	
	Возврат КонтекстноеМеню;
	
КонецФункции

Процедура УточнитьДоступныеВидыСравнения(ДоступныеВидыСравнения)
	
	НедоступныеВидыСравнения = Новый Массив;
	НедоступныеВидыСравнения.Добавить(ВидСравненияКомпоновкиДанных.ВСписке);
	НедоступныеВидыСравнения.Добавить(ВидСравненияКомпоновкиДанных.НеВСписке);
	НедоступныеВидыСравнения.Добавить(ВидСравненияКомпоновкиДанных.ВСпискеПоИерархии);
	НедоступныеВидыСравнения.Добавить(ВидСравненияКомпоновкиДанных.НеВСпискеПоИерархии);
	
	Для Каждого Вид Из НедоступныеВидыСравнения Цикл 
		
		НайденныйВид = ДоступныеВидыСравнения.НайтиПоЗначению(Вид);
		
		Если НайденныйВид <> Неопределено Тогда 
			ДоступныеВидыСравнения.Удалить(НайденныйВид);
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

#КонецОбласти

#Область Расшифровка

Процедура ВыполнитьРасшифровку(ВыполненноеДействие, ПараметрВыполненногоДействия, ДополнительныеПараметры) Экспорт 
	
	Если ВыполненноеДействие = Неопределено
		Или ВыполненноеДействие = ДействиеОбработкиРасшифровкиКомпоновкиДанных.Нет Тогда 
		
		Возврат;
	КонецЕсли;
	
	Форма = ДополнительныеПараметры.Форма;
	Данные = ДополнительныеПараметры.Данные;
	СвойстваОбласти = ДополнительныеПараметры.СвойстваОбласти;
	Меню = ДополнительныеПараметры.Меню;
	
	Если СвойстваОбласти.ЭтоЗаголовок Тогда 
		
		СвойстваЗаголовка = СвойстваОбласти.СвойстваЗаголовка;
		
		Если ТипЗнч(ВыполненноеДействие) = Тип("Строка")
			И СвойстваЗаголовка.Свойство(ВыполненноеДействие)
			И Не СвойстваЗаголовка[ВыполненноеДействие] Тогда 
			
			ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Действие ""%1"" недоступно'"), Меню.НайтиПоЗначению(ВыполненноеДействие));
			
			ПоказатьПредупреждение(, ТекстСообщения);
			
		КонецЕсли;
		
		Если СтрНайти(СвойстваЗаголовка.ИдентификаторГруппировки, "/column/") = 0 Тогда 
			Возврат;
		КонецЕсли;
		
	КонецЕсли;
	
	Если ТипЗнч(ВыполненноеДействие) = Тип("Строка")
		И ВыполненноеДействие = "СнятьФильтр" Тогда 
		
		СнятьФильтр(Форма, СвойстваОбласти.СвойстваЗаголовка, Данные);
		Возврат;
		
	КонецЕсли;
	
	Если ТипЗнч(ВыполненноеДействие) = Тип("ВидСравненияКомпоновкиДанных")
		Или ТипЗнч(ВыполненноеДействие) = Тип("Строка") И СтрНачинаетсяС(ВыполненноеДействие, "Фильтровать") Тогда 
		
		Фильтровать(Форма, ВыполненноеДействие, СвойстваОбласти.СвойстваЗаголовка, Данные);
		Возврат;
		
	КонецЕсли;
	
	Если ТипЗнч(ВыполненноеДействие) = Тип("НаправлениеСортировкиКомпоновкиДанных") Тогда 
		
		Если ВыполненноеДействие = НаправлениеСортировкиКомпоновкиДанных.Возр Тогда 
			Команда = Форма.Команды.Найти("СортироватьПоВозрастанию");
		Иначе
			Команда = Форма.Команды.Найти("СортироватьПоУбыванию");
		КонецЕсли;
		
		Сортировать(Форма, Команда, СвойстваОбласти.СвойстваЗаголовка);
		Возврат;
		
	КонецЕсли;
	
	Если ТипЗнч(ВыполненноеДействие) = Тип("Строка")
		И ВыполненноеДействие = "ОчиститьОформление" Тогда 
		
		ОчиститьОформление(Форма, СвойстваОбласти.СвойстваЗаголовка);
		Возврат;
		
	КонецЕсли;
	
	Если ТипЗнч(ВыполненноеДействие) = Тип("Строка")
		И (ВыполненноеДействие = "ОформитьКрасным"
		Или ВыполненноеДействие = "ОформитьЖелтым"
		Или ВыполненноеДействие = "ОформитьЗеленым"
		Или ВыполненноеДействие = "ОформитьОтрицательные"
		Или ВыполненноеДействие = "ОформитьПоложительные"
		Или ВыполненноеДействие = "УстановитьВысотуСтроки"
		Или ВыполненноеДействие = "УстановитьШиринуКолонки"
		Или ВыполненноеДействие = "ОформитьЕще") Тогда 
		
		Команда = Форма.Команды.Найти(ВыполненноеДействие);
		
		Если Команда = Неопределено Тогда
			Команда = ВыполненноеДействие;
		КонецЕсли;
		
		Если ВыполненноеДействие = "ОформитьКрасным"
			Или ВыполненноеДействие = "ОформитьОтрицательные" Тогда 
			
			ОформитьКрасным(Форма, Команда, СвойстваОбласти.СвойстваЗаголовка, Данные.Значения);
			
		ИначеЕсли ВыполненноеДействие = "ОформитьЖелтым" Тогда 
			
			ОформитьЖелтым(Форма, Команда, СвойстваОбласти.СвойстваЗаголовка, Данные.Значения);
			
		ИначеЕсли ВыполненноеДействие = "ОформитьЗеленым"
			Или ВыполненноеДействие = "ОформитьПоложительные" Тогда 
			
			ОформитьЗеленым(Форма, Команда, СвойстваОбласти.СвойстваЗаголовка, Данные.Значения);
			
		ИначеЕсли ВыполненноеДействие = "УстановитьВысотуСтроки" Тогда 
			
			УстановитьВысотуСтроки(Форма, Команда, СвойстваОбласти.СвойстваЗаголовка);
			
		ИначеЕсли ВыполненноеДействие = "УстановитьШиринуКолонки" Тогда 
			
			УстановитьШиринуКолонки(Форма, Команда, СвойстваОбласти.СвойстваЗаголовка);
			
		ИначеЕсли ВыполненноеДействие = "ОформитьЕще" Тогда 
			
			ОформитьЕще(Форма, Команда, СвойстваОбласти.СвойстваЗаголовка, Данные.Значения);
			
		КонецЕсли;
		
		Возврат;
		
	КонецЕсли;
	
	Если ВыполненноеДействие = ДействиеОбработкиРасшифровкиКомпоновкиДанных.ОткрытьЗначение Тогда
		
		ПоказатьЗначение(, Данные.Значение);
		Возврат;
		
	КонецЕсли;
	
	Если ВыполненноеДействие =  "РасшифроватьПоДетальнымЗаписям" Тогда 
		ПараметрВыполненногоДействия = Новый НастройкиКомпоновкиДанных;
		ГруппировкаКомпоновкиДанных = ПараметрВыполненногоДействия.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
		ГруппировкаКомпоновкиДанных.Имя = "Расшифровка";
		
		ДополнительныеПараметры.Вставить("Настройки", ПараметрВыполненногоДействия);
		ОткрытьФормуОтчета(Форма, ДополнительныеПараметры);
		Возврат;
	КонецЕсли;
	
	Если ВыполненноеДействие = ДействиеОбработкиРасшифровкиКомпоновкиДанных.Расшифровать Тогда
		
		ДополнительныеПараметры.Вставить("Настройки", ПараметрВыполненногоДействия);
		ОткрытьФормуОтчета(Форма, ДополнительныеПараметры);
		
	КонецЕсли;
	
КонецПроцедуры

Процедура ОткрытьФормуОтчета(Форма, ПараметрыОткрытия)
	
	НастройкиОтчета = Форма.НастройкиОтчета;
	Расшифровка = ПараметрыОткрытия.Расшифровка;
	
	Расшифровка = Новый ОписаниеОбработкиРасшифровкиКомпоновкиДанных(
		Форма.ОтчетДанныеРасшифровки, ПараметрыОткрытия.Расшифровка, ПараметрыОткрытия.Настройки); 
	
	ПредставлениеВарианта = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = '%1 (Расшифровка)'"), Форма.ПредставлениеТекущегоВарианта);
	
	ПараметрыФормы = Новый Структура;
	ПараметрыФормы.Вставить("Расшифровка", Расшифровка);
	ПараметрыФормы.Вставить("СформироватьПриОткрытии", Истина);
	ПараметрыФормы.Вставить("ПредставлениеВарианта", ПредставлениеВарианта);
	ПараметрыФормы.Вставить("НастройкиОтчета", НастройкиОтчета);
	
	Если ПараметрыОткрытия.Свойство("Отбор")
		И ТипЗнч(ПараметрыОткрытия.Отбор) = Тип("Структура") Тогда 
		
		ПараметрыФормы.Вставить("Отбор", ПараметрыОткрытия.Отбор);
	КонецЕсли;
	
	ОткрытьФорму(НастройкиОтчета.ПолноеИмя + ".Форма", ПараметрыФормы, Форма, Форма.УникальныйИдентификатор);
	
КонецПроцедуры

#КонецОбласти

#КонецОбласти

#Область Общее

// Параметры:
//  Форма - ФормаКлиентскогоПриложения
//  БезАвтоПолей - Булево
//
// Возвращаемое значение:
//  КомпоновщикНастроекКомпоновкиДанных
//
Функция КомпоновщикНастроекОтчета(Форма, БезАвтоПолей = Ложь)
	
	Если СтрЗаканчиваетсяНа(Форма.ИмяФормы, "КонтекстнаяНастройкаОтчета") Тогда 
		
		КомпоновщикНастроек = Форма.КомпоновщикНастроек;
		Если БезАвтоПолей Тогда 
			КомпоновщикНастроек.РазвернутьАвтоПоля();
		КонецЕсли;
	Иначе
		НастройкиОтчета = Форма.НастройкиОтчета; // см. ВариантыОтчетов.НастройкиФормыОтчета
		СвойстваРезультата = НастройкиОтчета.СвойстваРезультата; // см. ВариантыОтчетовСлужебный.СвойстваРезультатаОтчета
		
		Если БезАвтоПолей Тогда
			КомпоновщикНастроек = СвойстваРезультата.КомпоновщикНастроекБезАвтоПолей;
		Иначе
			КомпоновщикНастроек = СвойстваРезультата.КомпоновщикНастроек;
		КонецЕсли;
	КонецЕсли;
	
	Возврат КомпоновщикНастроек;
	
КонецФункции

// Параметры:
//   Форма - ФормаКлиентскогоПриложения
//   ИдентификаторНастроек - ИдентификаторКомпоновкиДанных
//                         - Неопределено
//   БезАвтоПолей - Булево
//
// Возвращаемое значение:
//  НастройкиКомпоновкиДанных
//
Функция ИспользуемыеНастройки(Форма, ИдентификаторНастроек = Неопределено, БезАвтоПолей = Ложь)
	
	КомпоновщикНастроек = КомпоновщикНастроекОтчета(Форма, БезАвтоПолей);
	ИспользуемыеНастройки = КомпоновщикНастроек.Настройки;
	
	Если ТипЗнч(ИдентификаторНастроек) <> Тип("ИдентификаторКомпоновкиДанных") Тогда 
		Возврат ИспользуемыеНастройки;
	КонецЕсли;
	
	НастройкиПоИдентификатору = ИспользуемыеНастройки.ПолучитьОбъектПоИдентификатору(ИдентификаторНастроек);
	
	Если НастройкиПоИдентификатору = Неопределено Тогда 
		Возврат ИспользуемыеНастройки;
	КонецЕсли;
	
	Возврат НастройкиПоИдентификатору;
	
КонецФункции

// Параметры:
//  Форма - ФормаКлиентскогоПриложения
//
// Возвращаемое значение:
//  Соответствие
//
Функция ЗаголовкиОтчета(Форма)
	
	Если СтрЗаканчиваетсяНа(Форма.ИмяФормы, "Форма")
		Или СтрЗаканчиваетсяНа(Форма.ИмяФормы, "ФормаОтчета")
		Или СтрЗаканчиваетсяНа(Форма.ИмяФормы, "КонтекстнаяНастройкаОтчета") Тогда 
		
		НастройкиОтчета = Форма.НастройкиОтчета; // см. ВариантыОтчетов.НастройкиФормыОтчета
		СвойстваРезультата = НастройкиОтчета.СвойстваРезультата; // см. ВариантыОтчетовСлужебный.СвойстваРезультатаОтчета
		
		Возврат СвойстваРезультата.Заголовки;
	КонецЕсли;
	
	Возврат Форма.ЗаголовкиОтчета;
	
КонецФункции

// Параметры:
//  Форма - ФормаКлиентскогоПриложения
//
// Возвращаемое значение:
//   см. ВариантыОтчетовСлужебный.СтандартныеСвойстваЗаголовкаОтчета
//
Функция СвойстваЗаголовкаОтчета(Форма)
	
	Если СтрЗаканчиваетсяНа(Форма.ИмяФормы, "Форма")
		Или СтрЗаканчиваетсяНа(Форма.ИмяФормы, "ФормаОтчета") Тогда 
		
		Заголовки = ЗаголовкиОтчета(Форма);
		Поле = Форма.ОтчетТабличныйДокумент; // ПолеФормы, РасширениеПоляФормыДляПоляТабличногоДокумента
		Область = Поле.ТекущаяОбласть; // ОбластьЯчеекТабличногоДокумента
		
		Возврат Заголовки[Область.Имя];
		
	КонецЕсли;
	
	Возврат Форма.СвойстваЗаголовка;
	
КонецФункции

Процедура УточнитьИмяКоллекции(ИмяКоллекции, Обработчик)
	
	ДополнительныеПараметры = Обработчик.ДополнительныеПараметры;
	СвойстваЗаголовка = ДополнительныеПараметры.СвойстваЗаголовка;
	
	Если СвойстваЗаголовка = Неопределено Тогда 
		Возврат;
	КонецЕсли;
	
	Если СвойстваЗаголовка.ТипПоля = Тип("ПолеГруппировкиКомпоновкиДанных") Тогда 
		ИмяКоллекции = "ПоляГруппировки";
	КонецЕсли;
	
	ДополнительныеПараметры.Вставить("ИмяКоллекции", ИмяКоллекции);
	
КонецПроцедуры

Функция ИдентификаторЭлементаСтруктурыНастроек(Форма, ИдентификаторУзлаНастроек)
	
	Если ИдентификаторУзлаНастроек <> Неопределено Тогда 
		Возврат ИдентификаторУзлаНастроек;
	КонецЕсли;
	
	Если СтрЗаканчиваетсяНа(Форма.ИмяФормы, "Форма")
		Или СтрЗаканчиваетсяНа(Форма.ИмяФормы, "ФормаОтчета") Тогда 
		
		Возврат Неопределено;
	КонецЕсли;
	
	Возврат Форма.ИдентификаторЭлементаСтруктурыНастроек;
	
КонецФункции

Функция ДействиеКоманды(Команда)
	
	Если Команда = Неопределено Тогда 
		Возврат Неопределено;
	КонецЕсли;
	
	Если ТипЗнч(Команда) = Тип("Строка") Тогда
		Возврат Команда;
	КонецЕсли;
	
	Возврат ?(ЗначениеЗаполнено(Команда.Действие), Команда.Действие, Команда.Имя);
	
КонецФункции

Функция ДетальныеЗаписи(ЭлементыСтруктуры, ДетальныеЗаписи = Неопределено)
	
	Для Каждого Элемент Из ЭлементыСтруктуры Цикл 
		
		ТипЭлемента = ТипЗнч(Элемент);
		
		Если ТипЭлемента = Тип("ГруппировкаКомпоновкиДанных")
			Или ТипЭлемента = Тип("ГруппировкаТаблицыКомпоновкиДанных") Тогда 
			
			ПоляГруппировки = Элемент.ПоляГруппировки.Элементы;
			
			Если ПоляГруппировки.Количество() = 0 Тогда 
				ДетальныеЗаписи = Элемент;
			Иначе
				ДетальныеЗаписи(Элемент.Структура, ДетальныеЗаписи);
			КонецЕсли;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат ДетальныеЗаписи;
	
КонецФункции

Процедура ОповеститьОЗавершенииКонтекстнойНастройки(Форма, Действие, ТекущееПоле = Неопределено)
	
	ЭтоФормОтчета = СтрЗаканчиваетсяНа(Форма.ИмяФормы, "Форма")
		Или СтрЗаканчиваетсяНа(Форма.ИмяФормы, "ФормаОтчета");
	
	КомпоновщикНастроек = КомпоновщикНастроекОтчета(Форма);
	ИспользуемыеНастройки = КомпоновщикНастроек.Настройки;
	
	ДобавитьНастройкиВСтек(Форма, ИспользуемыеНастройки, Действие, ТекущееПоле);
	
	ИдентификаторВладельца = ?(ЭтоФормОтчета, Форма.УникальныйИдентификатор, Форма.ВладелецФормы.УникальныйИдентификатор);
	
	Результат = РезультатКонтекстнойНастройки(КомпоновщикНастроек, Действие, ИдентификаторВладельца);
	
	Если ЭтоФормОтчета Тогда 
		Оповестить(Действие, Результат, ЭтотОбъект);
	Иначе
		Форма.ОповеститьОВыборе(Результат);
	КонецЕсли;
	
КонецПроцедуры

// Параметры:
//  КомпоновщикНастроек - КомпоновщикНастроекКомпоновкиДанных
//  Действие - Строка
//  ИдентификаторВладельца - УникальныйИдентификатор
//
// Возвращаемое значение:
//   Структура:
//     * Действие - Строка
//     * ИдентификаторВладельца - УникальныйИдентификатор
//     * КомпоновщикНастроек - КомпоновщикНастроекКомпоновкиДанных
//     * Переформировать - Булево
//     * ВариантМодифицирован - Булево
//     * ПользовательскиеНастройкиМодифицированы - Булево
//     * СброситьПользовательскиеНастройки - Булево
//
Функция РезультатКонтекстнойНастройки(КомпоновщикНастроек, Действие, ИдентификаторВладельца) Экспорт 
	
	Результат = Новый Структура;
	Результат.Вставить("КомпоновщикНастроекКД", КомпоновщикНастроек);
	Результат.Вставить("Действие", Действие);
	Результат.Вставить("ИдентификаторВладельца", ИдентификаторВладельца);
	Результат.Вставить("Переформировать", Ложь);
	Результат.Вставить("ВариантМодифицирован", Истина);
	Результат.Вставить("ПользовательскиеНастройкиМодифицированы", Истина);
	Результат.Вставить("СброситьПользовательскиеНастройки", Истина);
	
	Возврат Результат;
	
КонецФункции

Функция СобытияКонтекстнойНастройки()
	
	События = Новый Соответствие;
	События.Вставить("СгруппироватьПоВыбранномуПолю", Истина);
	
	События.Вставить("ВставитьПолеСлева", Истина);
	События.Вставить("ВставитьПолеСправа", Истина);
	События.Вставить("ВставитьГруппировкуВыше", Истина);
	События.Вставить("ВставитьГруппировкуНиже", Истина);
	
	События.Вставить("ПереместитьПолеВлево", Истина);
	События.Вставить("ПереместитьПолеВправо", Истина);
	События.Вставить("ПереместитьПолеВыше", Истина);
	События.Вставить("ПереместитьПолеНиже", Истина);
	
	События.Вставить("СкрытьПоле", Истина);
	События.Вставить("ПереименоватьПоле", Истина);
	
	События.Вставить("СнятьФильтр", Истина);
	События.Вставить("Фильтровать", Истина);
	События.Вставить("ФильтроватьИСформировать", Истина);
	
	События.Вставить("СортироватьПоВозрастанию", Истина);
	События.Вставить("СортироватьПоУбыванию", Истина);
	
	События.Вставить("ОчиститьОформление", Истина);
	
	События.Вставить("ОформитьКрасным", Истина);
	События.Вставить("ОформитьЖелтым", Истина);
	События.Вставить("ОформитьЗеленым", Истина);
	
	События.Вставить("ОформитьОтрицательные", Истина);
	События.Вставить("ОформитьПоложительные", Истина);
	
	События.Вставить("УстановитьВысотуСтроки", Истина);
	События.Вставить("УстановитьШиринуКолонки", Истина);
	
	События.Вставить("ОформитьЕще", Истина);
	
	Возврат События;
	
КонецФункции

Функция ДействиеДоступно(Форма, Команда = Неопределено, СвойстваЗаголовка = Неопределено)
	
	Если СвойстваЗаголовка = Неопределено Тогда
		СвойстваЗаголовка = СвойстваЗаголовкаОтчета(Форма);
	КонецЕсли;
	
	ДействиеКоманды = ДействиеКоманды(Команда);
	
	Если ТипЗнч(СвойстваЗаголовка) <> Тип("Структура")
		Или ДействиеКоманды <> Неопределено И Не СвойстваЗаголовка[ДействиеКоманды] Тогда 
		
		ПоказатьПредупреждение(, НСтр("ru = 'Действие недоступно'"));
		Возврат Ложь;
		
	КонецЕсли;
	
	Возврат Истина;
	
КонецФункции

Функция ДействиеНадПолемДоступно(Действие, СвойстваЗаголовка)
	
	Если Не СвойстваЗаголовка[Действие] Тогда 
		
		ТекстПредупреждения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Действие недоступно для поля %1'"), СвойстваЗаголовка.Текст);
		
		ПоказатьПредупреждение(, ТекстПредупреждения);
		
		Возврат Ложь;
		
	КонецЕсли;
	
	Возврат Истина;
	
КонецФункции

Процедура СпроситьОУведомленииПользователей(ОписаниеОповещения, КоличествоПользователей) Экспорт 
	
	ПредставлениеКоличестваПользователей = СтроковыеФункцииКлиентСервер.СтрокаСЧисломДляЛюбогоЯзыка(
		НСтр("ru = '; %1 пользователя; ; %1 пользователей; %1 пользователей; %1 пользователей'"),
		КоличествоПользователей);
	
	ТекстВопроса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = 'Уведомить в чате %1 о том, что этот вариант будет отображен на их панели отчетов?'"),
		ПредставлениеКоличестваПользователей);
	
	ПоказатьВопрос(ОписаниеОповещения, ТекстВопроса, РежимДиалогаВопрос.ДаНет, 60, КодВозвратаДиалога.Нет);
	
КонецПроцедуры

Процедура ДобавитьФормулы(Настройки, КоллекцияПолей, ОписаниеФормул) Экспорт 
	
	Для Каждого ОписаниеФормулы Из ОписаниеФормул Цикл 
		ДобавитьФормулу(Настройки, КоллекцияПолей, ОписаниеФормулы);
	КонецЦикла;
	
КонецПроцедуры

Процедура ДобавитьФормулу(Настройки, КоллекцияПолей, ОписаниеФормулы) Экспорт 
	
	ЭтоПользовательскоеПолеВыражениеКомпоновкиДанных = ТипЗнч(ОписаниеФормулы) = Тип("ПользовательскоеПолеВыражениеКомпоновкиДанных");
	Если Не ЭтоПользовательскоеПолеВыражениеКомпоновкиДанных И (ТипЗнч(ОписаниеФормулы) <> Тип("Структура")
		Или Не ОписаниеФормулы.Свойство("Формула")) Тогда
		Возврат; 
	КонецЕсли;
		
	Если ЭтоПользовательскоеПолеВыражениеКомпоновкиДанных Тогда
		ПутьКДанным = ОписаниеФормулы.ПутьКДанным;
		ОписаниеФормулы = ОписаниеФормулыПоОбразцу(ОписаниеФормулы);
	КонецЕсли;
	Формулы = Настройки.ПользовательскиеПоля.Элементы;
	
	Если ЗначениеЗаполнено(ПутьКДанным) Тогда 
		Формула = ВариантыОтчетовСлужебныйКлиентСервер.ФормулаПоПутиКДанным(Настройки, ПутьКДанным);
	Иначе
		Формула = ФормулаПоВыражению(Формулы, ОписаниеФормулы.Формула);
	КонецЕсли;
	
	Если Формула = Неопределено Тогда 
		Формула = Формулы.Добавить(Тип("ПользовательскоеПолеВыражениеКомпоновкиДанных"));
	КонецЕсли;
	
	ДополнительныеПараметры = Новый Структура("КоллекцияПолей, Формула", КоллекцияПолей, Формула);
	УстановитьСвойстваФормулы(ОписаниеФормулы, ДополнительныеПараметры);
	
	ОписаниеФормулы = КоллекцияПолей.НайтиПоле(Новый ПолеКомпоновкиДанных(Формула.ПутьКДанным));
	УстановитьВыражениеИтоговыхЗаписей(Формула, ОписаниеФормулы);
	
КонецПроцедуры

Функция ФормулаПоВыражению(Формулы, Выражение)
	
	Для Каждого Формула Из Формулы Цикл 
		
		Если ТипЗнч(Формула) <> Тип("ПользовательскоеПолеВыражениеКомпоновкиДанных") Тогда
			Продолжить;
		КонецЕсли;

		Если СокрЛП(Выражение) = Формула.ПолучитьВыражениеДетальныхЗаписей() Тогда 
			Возврат Формула;
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат Неопределено;
	
КонецФункции

Процедура ИзменитьФормулу(Форма, Настройки, ПутьКДанным, ИмяКоллекции = "ДоступныеПоляВыбора") Экспорт 
	
	Формула = ВариантыОтчетовСлужебныйКлиентСервер.ФормулаПоПутиКДанным(Настройки, ПутьКДанным);
	
	Если ТипЗнч(Формула) <> Тип("ПользовательскоеПолеВыражениеКомпоновкиДанных") Тогда
		ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Редактирование поля ""%1""доступно в форме настроек для технического специалиста на закладке ""Пользовательские поля""'"),
			Формула.Заголовок);
		
		ПоказатьПредупреждение(Неопределено, ТекстСообщения);
		Возврат;
	КонецЕсли;
	
	ПараметрыРедактированияФормулы = КонструкторФормулКлиент.ПараметрыРедактированияФормулы();
	ПараметрыРедактированияФормулы.Операнды = Форма.НастройкиОтчета.АдресСхемы;
	ПараметрыРедактированияФормулы.ИмяКоллекцииСКДОперандов = ИмяКоллекции;
	ПараметрыРедактированияФормулы.Формула = Формула.ПолучитьВыражениеДетальныхЗаписей();
	ПараметрыРедактированияФормулы.Наименование = Формула.Заголовок;
	ПараметрыРедактированияФормулы.ДляЗапроса = Истина;
	
	ДополнительныеПараметры = Новый Структура();
	ДополнительныеПараметры.Вставить("КоллекцияПолей", Настройки.ДоступныеПоляВыбора);
	ДополнительныеПараметры.Вставить("Формула", Формула);
	
	Обработчик = Новый ОписаниеОповещения("ПослеИзмененияФормулы", Форма, ДополнительныеПараметры);
	КонструкторФормулКлиент.НачатьРедактированиеФормулы(ПараметрыРедактированияФормулы, Обработчик);
	
КонецПроцедуры

// Параметры:
//  ОписаниеФормулы - ДоступноеПолеКомпоновкиДанных
//                  - Структура:
//                      * Формула - Строка
//                      * ПредставлениеФормулы - Строка
//                      * Наименование - Строка
//  ДополнительныеПараметры - Структура:
//    * Формула - ПользовательскоеПолеВыражениеКомпоновкиДанных
//    * КоллекцияПолей - ДоступныеПоляКомпоновкиДанных
//  
Процедура ПослеИзмененияФормулы(ОписаниеФормулы, ДополнительныеПараметры) Экспорт 
	
	Если ТипЗнч(ОписаниеФормулы) <> Тип("Структура")
		Или Не ОписаниеФормулы.Свойство("Формула") Тогда 
		
		Возврат;
	КонецЕсли;
	
	УстановитьСвойстваФормулы(ОписаниеФормулы, ДополнительныеПараметры);
	
КонецПроцедуры

// Параметры:
//  Образец - ПользовательскоеПолеВыражениеКомпоновкиДанных
// 
// Возвращаемое значение:
//  Структура:
//    * Формула - Строка
//    * ПредставлениеФормулы - Строка
//    * Наименование - Строка
//
Функция ОписаниеФормулыПоОбразцу(Образец)
	
	ОписаниеФормулы = Новый Структура;
	ОписаниеФормулы.Вставить("Формула", Образец.ПолучитьВыражениеДетальныхЗаписей());
	ОписаниеФормулы.Вставить("ПредставлениеФормулы", Образец.ПолучитьПредставлениеВыраженияДетальныхЗаписей());
	ОписаниеФормулы.Вставить("Наименование", Образец.Заголовок);
	
	Возврат ОписаниеФормулы;
	
КонецФункции

// Параметры:
//  ОписаниеФормулы - ДоступноеПолеКомпоновкиДанных
//                  - Структура:
//                      * Формула - Строка
//                      * ПредставлениеФормулы - Строка
//                      * Наименование - Строка
//  ДополнительныеПараметры - Структура:
//    * Формула - ПользовательскоеПолеВыражениеКомпоновкиДанных
//    * КоллекцияПолей - ДоступныеПоляКомпоновкиДанных
//
Процедура УстановитьСвойстваФормулы(ОписаниеФормулы, ДополнительныеПараметры) 
	
	Выражение = СокрЛП(ОписаниеФормулы.Формула);
	ПредставлениеВыражения = СокрЛП(ОписаниеФормулы.ПредставлениеФормулы);
	Заголовок = СокрЛП(ОписаниеФормулы.Наименование);
	
	Формула = ДополнительныеПараметры.Формула;
	Формула.УстановитьВыражениеДетальныхЗаписей(Выражение);
	Формула.Заголовок = ?(ЗначениеЗаполнено(Заголовок), Заголовок, ПредставлениеВыражения);
	
	ОписаниеФормулы = ДополнительныеПараметры.КоллекцияПолей.НайтиПоле(Новый ПолеКомпоновкиДанных(Формула.ПутьКДанным));
	УстановитьВыражениеИтоговыхЗаписей(Формула, ОписаниеФормулы);
	
КонецПроцедуры

Процедура УстановитьВыражениеИтоговыхЗаписей(Формула, ОписаниеФормулы)
	
	Если ОписаниеФормулы = Неопределено
		Или ОписаниеФормулы.Тип.Типы().Количество() > 1
		Или Не ОписаниеФормулы.Тип.СодержитТип(Тип("Число")) Тогда 
		
		Возврат;
	КонецЕсли;
	
	ВыражениеДетальныхЗаписей = Формула.ПолучитьВыражениеДетальныхЗаписей();
	
	Если ПустаяСтрока(ВыражениеДетальныхЗаписей) Тогда
		Возврат;
	КонецЕсли;
	
	Если ВыражениеСодержитАгрегатнуюФункцию(ВыражениеДетальныхЗаписей) Тогда
		ВыражениеИтоговыхЗаписей = ВыражениеДетальныхЗаписей;
	Иначе
		ВыражениеИтоговыхЗаписей = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			"Сумма(%1)", ВыражениеДетальныхЗаписей);
	КонецЕсли;
	
	Формула.УстановитьВыражения(ВыражениеДетальныхЗаписей, ВыражениеИтоговыхЗаписей);
	
КонецПроцедуры

Функция ВыражениеСодержитАгрегатнуюФункцию(Знач Выражение)
	
	Выражение = ВРег(СтрСоединить(СтрРазделить(Выражение, " " + Символы.Таб + Символы.ПС, Ложь), ""));
	
	Если СтрНайти(Выражение, "СУММА(")
		Или СтрНайти(Выражение, "КОЛИЧЕСТВО(")
		Или СтрНайти(Выражение, "МАКСИМУМ(")
		Или СтрНайти(Выражение, "МИНИМУМ(")
		Или СтрНайти(Выражение, "СРЕДНЕЕ(") Тогда
		Возврат Истина;
	КонецЕсли;
	
	Возврат Ложь;
	
КонецФункции

Функция ПараметрыСохраненияВариантаОтчетаВФайл(Форма) Экспорт 
	
	ПараметрыСохранения = Новый Структура();
	
	НастройкиОтчета = Форма.НастройкиОтчета;
	КомпоновщикНастроек = Форма.Отчет.КомпоновщикНастроек;
	
	ПараметрыСохранения.Вставить("Ссылка",  НастройкиОтчета.ВариантСсылка);
	ПараметрыСохранения.Вставить("ИмяОтчета",  НастройкиОтчета.ПолноеИмя);
	ПараметрыСохранения.Вставить("Настройки",  КомпоновщикНастроек.Настройки);
	ПараметрыСохранения.Вставить("КлючВарианта",  Форма.КлючТекущегоВарианта);
	ПараметрыСохранения.Вставить("ПредставлениеВарианта",  Форма.ПредставлениеТекущегоВарианта);
	ПараметрыСохранения.Вставить("КлючПользовательскихНастроек",  Форма.КлючТекущихПользовательскихНастроек);
	ПараметрыСохранения.Вставить("ПредставлениеПользовательскихНастроек",  Форма.ПредставлениеТекущихПользовательскихНастроек);
	
	Возврат ПараметрыСохранения;
	
КонецФункции

Функция ЭтоФормаОтчета(Форма)
	
	Возврат СтрЗаканчиваетсяНа(Форма.ИмяФормы, "Форма")
		Или СтрЗаканчиваетсяНа(Форма.ИмяФормы, "ФормаОтчета");
	
КонецФункции

#Область СтекНастроек

Процедура ДобавитьНастройкиВСтек(Форма, Настройки, Действие, ТекущееПоле = Неопределено) Экспорт 
	
	СтекНастроек = СтекНастроекОтчета(Форма);
	
	Если СтекНастроек = Неопределено Тогда 
		Возврат;
	КонецЕсли;
	
	УдалитьРазрывСтекаНастроек(СтекНастроек);
	СброситьПометкиСтекаНастроек(СтекНастроек);
	
	Запись = СтекНастроек.Добавить();
	Запись.Порядок = СтекНастроек.Количество();
	Запись.Пометка = Истина;
	Запись.Настройки = Настройки;
	Запись.Действие = Действие;
	Запись.ПредставлениеДействия = ПредставлениеДействияСтекаНастроек(Форма, Запись, ТекущееПоле);
	
	УдалитьИзбыточныеЗаписиСтекаНастроек(СтекНастроек);
	
КонецПроцедуры

// Параметры:
//  Форма - ФормаКлиентскогоПриложения
//  ЗаписьСтекаНастроек - ДанныеФормыЭлементКоллекции:
//    * Действие - Строка
//    * Настройки - НастройкиКомпоновкиДанных
//    * Пометка - Булево
//    * Порядок - Число
//    * ПредставлениеДействия - Строка
//  ТекущееПоле - Неопределено
//              - Строка
// 
// Возвращаемое значение:
//  Строка
//
Функция ПредставлениеДействияСтекаНастроек(Форма, ЗаписьСтекаНастроек, ТекущееПоле)
	
	Действие = ЗаписьСтекаНастроек.Действие;
	
	Если ТекущееПоле = Неопределено Тогда 
		
		СвойстваЗаголовка = СвойстваЗаголовкаОтчета(Форма);
		ТекущееПоле = ?(СвойстваЗаголовка = Неопределено, Неопределено, СвойстваЗаголовка.Текст);
		
	КонецЕсли;
	
	НастройкиОтчета = Форма.НастройкиОтчета; // см. ВариантыОтчетов.НастройкиФормыОтчета
	ПредставлениеСобытия = СтрЗаменить(НастройкиОтчета.СобытияНастроек[Действие], "...", "");
	
	Если ЗначениеЗаполнено(ТекущееПоле) Тогда 
		
		Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			"%1 '%2'", ПредставлениеСобытия, ТекущееПоле);
		
	КонецЕсли;
	
	Возврат ПредставлениеСобытия;

КонецФункции

Функция СтекНастроекОтчета(Форма)
	
	Если ЭтоФормаОтчета(Форма) Тогда 
		Возврат Форма.СтекНастроек;
	КонецЕсли;
	
	ВладелецФормы = Форма.ВладелецФормы;
	
	Если ВладелецФормы <> Неопределено
		И ЭтоФормаОтчета(ВладелецФормы) Тогда 
		
		Возврат ВладелецФормы.СтекНастроек;
	КонецЕсли;
	
	Возврат Неопределено;
	
КонецФункции

Процедура УдалитьРазрывСтекаНастроек(СтекНастроек)
	
	КоличествоНастроекСтека = СтекНастроек.Количество();
	
	Если КоличествоНастроекСтека = 0 Тогда 
		Возврат;
	КонецЕсли;
	
	СтекНастроек.Сортировать("Порядок Возр");
	
	ТекущиеНастройкиСтека = СтекНастроек.НайтиСтроки(Новый Структура("Пометка", Истина));
	
	Если ТекущиеНастройкиСтека.Количество() = 0 Тогда 
		Возврат;
	КонецЕсли;
	
	ИндексТекущихНастроек = СтекНастроек.Индекс(ТекущиеНастройкиСтека[0]);
	ГраницаСтекаНастроек = КоличествоНастроекСтека - 1;
	
	Если ИндексТекущихНастроек = ГраницаСтекаНастроек Тогда 
		Возврат;
	КонецЕсли;
	
	Пока ГраницаСтекаНастроек > ИндексТекущихНастроек Цикл 
		
		СтекНастроек.Удалить(ГраницаСтекаНастроек);
		ГраницаСтекаНастроек = ГраницаСтекаНастроек - 1;
		
	КонецЦикла;
	
КонецПроцедуры

Процедура СброситьПометкиСтекаНастроек(СтекНастроек) Экспорт 
	
	Для Каждого Запись Из СтекНастроек Цикл 
		Запись.Пометка = Ложь;
	КонецЦикла;
	
КонецПроцедуры

Процедура УдалитьИзбыточныеЗаписиСтекаНастроек(СтекНастроек)
	
	Если СтекНастроек.Количество() <= ВариантыОтчетовСлужебныйКлиентСервер.МаксимальныйРазмерСтекаНастроек() Тогда 
		Возврат;
	КонецЕсли;
	
	СтекНастроек.Удалить(0);
	
	Порядок = 0;
	
	Для Каждого Запись Из СтекНастроек Цикл 
		
		Порядок = Порядок + 1;
		Запись.Порядок = Порядок;
		
	КонецЦикла;
	
КонецПроцедуры

#КонецОбласти

#КонецОбласти

#КонецОбласти
